1#[cfg(not(target_endian = "little"))]
2compile_error!("Zero-copy serialization requires a little-endian target");
3#[allow(unused_variables, unused_braces, unused_parens)]
4#[allow(clippy::identity_op)]
5pub mod reg {
6 pub mod udral {
7 pub mod physics {
8 pub mod acoustics {
9 pub mod note_0_1 {
10 #[cfg_attr(
15 not(doctest),
16 doc = " Description of a generic musical note in terms of basic physical quantities.\n\n This type may be used to control sound notification emitters assuming the best effort policy:\n if the requested parameters exceed the capabilities of the emitter, the closest possible values should be assumed."
17 )]
18 #[derive(
19 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
20 )]
21 #[repr(C, packed)]
22 pub struct Note {
23 pub frequency: crate::uavcan::si::unit::frequency::scalar_1_0::Scalar,
29 pub duration: crate::uavcan::si::unit::duration::scalar_1_0::Scalar,
35 pub acoustic_power: crate::uavcan::si::unit::power::scalar_1_0::Scalar,
41 }
42 impl ::emcyphal_encoding::DataType for Note {
43 const EXTENT_BYTES: Option<u32> = None;
45 }
46 impl ::emcyphal_encoding::Message for Note {}
47 impl ::emcyphal_encoding::BufferType for Note {
48 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
49 }
50 impl Note {}
51 impl ::emcyphal_encoding::Serialize for Note {
52 fn size_bits(&self) -> usize {
53 96
54 }
55 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
56 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
57 }
58 }
59 impl ::emcyphal_encoding::Deserialize for Note {
60 fn deserialize(
61 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
62 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
63 where
64 Self: Sized,
65 {
66 Ok(Self::deserialize_zero_copy(cursor))
67 }
68 }
69 #[test]
70 fn test_layout() {
71 assert_eq!(::core::mem::size_of::<Note>() * 8, 96);
72 assert_eq!(::core::mem::offset_of!(Note, frequency) * 8, 0);
73 assert_eq!(::core::mem::offset_of!(Note, duration) * 8, 32);
74 assert_eq!(::core::mem::offset_of!(Note, acoustic_power) * 8, 64);
75 }
76 }
77 }
78 pub mod dynamics {
79 pub mod rotation {
80 pub mod planar_0_1 {
81 #[cfg_attr(
86 not(doctest),
87 doc = " Positive torque is co-directed with positive position/velocity/acceleration.\n Provided states may allow the consumer to deduce certain hidden states such as the moment of inertia."
88 )]
89 #[derive(
90 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
91 )]
92 #[repr(C, packed)]
93 pub struct Planar {
94pub kinematics: crate::reg::udral::physics::kinematics::rotation::planar_0_1::Planar,
100#[cfg_attr(not(doctest), doc = " NaN if unknown")]
101pub torque: crate::uavcan::si::unit::torque::scalar_1_0::Scalar,
107}
108 impl ::emcyphal_encoding::DataType for Planar {
109 const EXTENT_BYTES: Option<u32> = None;
111 }
112 impl ::emcyphal_encoding::Message for Planar {}
113 impl ::emcyphal_encoding::BufferType for Planar {
114 type Buffer = ::emcyphal_encoding::StaticBuffer<16>;
115 }
116 impl Planar {}
117 impl ::emcyphal_encoding::Serialize for Planar {
118 fn size_bits(&self) -> usize {
119 128
120 }
121 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
122 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
123 }
124 }
125 impl ::emcyphal_encoding::Deserialize for Planar {
126 fn deserialize(
127 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
128 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
129 where
130 Self: Sized,
131 {
132 Ok(Self::deserialize_zero_copy(cursor))
133 }
134 }
135 #[test]
136 fn test_layout() {
137 assert_eq!(::core::mem::size_of::<Planar>() * 8, 128);
138 assert_eq!(::core::mem::offset_of!(Planar, kinematics) * 8, 0);
139 assert_eq!(::core::mem::offset_of!(Planar, torque) * 8, 96);
140 }
141 }
142 pub mod planar_ts_0_1 {
143 pub struct PlanarTs {
148pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
154pub value: crate::reg::udral::physics::dynamics::rotation::planar_0_1::Planar,
160}
161 impl ::emcyphal_encoding::DataType for PlanarTs {
162 const EXTENT_BYTES: Option<u32> = None;
164 }
165 impl ::emcyphal_encoding::Message for PlanarTs {}
166 impl ::emcyphal_encoding::BufferType for PlanarTs {
167 type Buffer = ::emcyphal_encoding::StaticBuffer<23>;
168 }
169 impl PlanarTs {}
170 impl ::emcyphal_encoding::Serialize for PlanarTs {
171 fn size_bits(&self) -> usize {
172 184
173 }
174 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
175 cursor.write_composite(&self.timestamp);
176 cursor.write_composite(&self.value);
177 }
178 }
179 impl ::emcyphal_encoding::Deserialize for PlanarTs {
180 fn deserialize(
181 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
182 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
183 where
184 Self: Sized,
185 {
186 Ok(PlanarTs {
187 timestamp: { cursor.read_composite()? },
188 value: { cursor.read_composite()? },
189 })
190 }
191 }
192 }
193 }
194 pub mod translation {
195 pub mod linear_0_1 {
196 #[cfg_attr(
201 not(doctest),
202 doc = " Positive force is co-directed with positive position/velocity/acceleration.\n Provided kinetic states may allow the consumer to deduce certain hidden states such as the mass of the load."
203 )]
204 #[derive(
205 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
206 )]
207 #[repr(C, packed)]
208 pub struct Linear {
209pub kinematics: crate::reg::udral::physics::kinematics::translation::linear_0_1::Linear,
215#[cfg_attr(not(doctest), doc = " NaN if unknown")]
216pub force: crate::uavcan::si::unit::force::scalar_1_0::Scalar,
222}
223 impl ::emcyphal_encoding::DataType for Linear {
224 const EXTENT_BYTES: Option<u32> = None;
226 }
227 impl ::emcyphal_encoding::Message for Linear {}
228 impl ::emcyphal_encoding::BufferType for Linear {
229 type Buffer = ::emcyphal_encoding::StaticBuffer<16>;
230 }
231 impl Linear {}
232 impl ::emcyphal_encoding::Serialize for Linear {
233 fn size_bits(&self) -> usize {
234 128
235 }
236 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
237 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
238 }
239 }
240 impl ::emcyphal_encoding::Deserialize for Linear {
241 fn deserialize(
242 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
243 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
244 where
245 Self: Sized,
246 {
247 Ok(Self::deserialize_zero_copy(cursor))
248 }
249 }
250 #[test]
251 fn test_layout() {
252 assert_eq!(::core::mem::size_of::<Linear>() * 8, 128);
253 assert_eq!(::core::mem::offset_of!(Linear, kinematics) * 8, 0);
254 assert_eq!(::core::mem::offset_of!(Linear, force) * 8, 96);
255 }
256 }
257 pub mod linear_ts_0_1 {
258 pub struct LinearTs {
263pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
269pub value: crate::reg::udral::physics::dynamics::translation::linear_0_1::Linear,
275}
276 impl ::emcyphal_encoding::DataType for LinearTs {
277 const EXTENT_BYTES: Option<u32> = None;
279 }
280 impl ::emcyphal_encoding::Message for LinearTs {}
281 impl ::emcyphal_encoding::BufferType for LinearTs {
282 type Buffer = ::emcyphal_encoding::StaticBuffer<23>;
283 }
284 impl LinearTs {}
285 impl ::emcyphal_encoding::Serialize for LinearTs {
286 fn size_bits(&self) -> usize {
287 184
288 }
289 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
290 cursor.write_composite(&self.timestamp);
291 cursor.write_composite(&self.value);
292 }
293 }
294 impl ::emcyphal_encoding::Deserialize for LinearTs {
295 fn deserialize(
296 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
297 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
298 where
299 Self: Sized,
300 {
301 Ok(LinearTs {
302 timestamp: { cursor.read_composite()? },
303 value: { cursor.read_composite()? },
304 })
305 }
306 }
307 }
308 }
309 }
310 pub mod electricity {
311 pub mod power_0_1 {
312 #[cfg_attr(
317 not(doctest),
318 doc = " DC or AC line electric power quantities. Generally, the following current sign convention applies:\n\n - Positive current flows from the electric power supply network to the load (e.g., an actuator).\n\n - If the electric network is the load itself powered from a source (e.g., battery), the current is negative."
319 )]
320 #[derive(
321 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
322 )]
323 #[repr(C, packed)]
324 pub struct Power {
325 pub current: crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
331 pub voltage: crate::uavcan::si::unit::voltage::scalar_1_0::Scalar,
337 }
338 impl ::emcyphal_encoding::DataType for Power {
339 const EXTENT_BYTES: Option<u32> = None;
341 }
342 impl ::emcyphal_encoding::Message for Power {}
343 impl ::emcyphal_encoding::BufferType for Power {
344 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
345 }
346 impl Power {}
347 impl ::emcyphal_encoding::Serialize for Power {
348 fn size_bits(&self) -> usize {
349 64
350 }
351 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
352 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
353 }
354 }
355 impl ::emcyphal_encoding::Deserialize for Power {
356 fn deserialize(
357 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
358 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
359 where
360 Self: Sized,
361 {
362 Ok(Self::deserialize_zero_copy(cursor))
363 }
364 }
365 #[test]
366 fn test_layout() {
367 assert_eq!(::core::mem::size_of::<Power>() * 8, 64);
368 assert_eq!(::core::mem::offset_of!(Power, current) * 8, 0);
369 assert_eq!(::core::mem::offset_of!(Power, voltage) * 8, 32);
370 }
371 }
372 pub mod power_ts_0_1 {
373 pub struct PowerTs {
378 pub timestamp:
384 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
385 pub value: crate::reg::udral::physics::electricity::power_0_1::Power,
391 }
392 impl ::emcyphal_encoding::DataType for PowerTs {
393 const EXTENT_BYTES: Option<u32> = None;
395 }
396 impl ::emcyphal_encoding::Message for PowerTs {}
397 impl ::emcyphal_encoding::BufferType for PowerTs {
398 type Buffer = ::emcyphal_encoding::StaticBuffer<15>;
399 }
400 impl PowerTs {}
401 impl ::emcyphal_encoding::Serialize for PowerTs {
402 fn size_bits(&self) -> usize {
403 120
404 }
405 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
406 cursor.write_composite(&self.timestamp);
407 cursor.write_composite(&self.value);
408 }
409 }
410 impl ::emcyphal_encoding::Deserialize for PowerTs {
411 fn deserialize(
412 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
413 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
414 where
415 Self: Sized,
416 {
417 Ok(PowerTs {
418 timestamp: { cursor.read_composite()? },
419 value: { cursor.read_composite()? },
420 })
421 }
422 }
423 }
424 pub mod source_0_1 {
425 #[cfg_attr(
430 not(doctest),
431 doc = " A generic source or sink of electric power (battery, turbogenerator, braking resistor, etc.).\n Low-pass filtering should be applied to avoid aliasing effects (as is the case everywhere else)."
432 )]
433 #[derive(
434 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
435 )]
436 #[repr(C, packed)]
437 pub struct Source {
438 #[cfg_attr(
439 not(doctest),
440 doc = " Total instant load power.\n Positive current flows into the source (power sinking).\n Negative current flows from the source to the power supply network (power sourcing)."
441 )]
442 pub power: crate::reg::udral::physics::electricity::power_0_1::Power,
448 #[cfg_attr(
449 not(doctest),
450 doc = " A pessimistic estimate of the amount of energy that can be reclaimed from the source in its current state.\n This may be dependent on the state of charge/health (for batteries), temperature, load profile, humidity, etc.\n Negative values may be reported to indicate overdischarge or depletion of the reserve energy.\n\n This value approximates (full_energy + int(load_power dt)) plus the environmental influences on the source.\n\n Having the instant power, the time to depletion is estimated as (energy/-power).\n When charging (for batteries), the remaining time to full charge can be found similarly as\n ((full_energy-energy)/power).\n\n For the sake of illustration, if this type was used to represent the state of a braking resistor,\n then this value would be negative indicating the amount of dissipated energy."
451 )]
452 pub energy: crate::uavcan::si::unit::energy::scalar_1_0::Scalar,
458 #[cfg_attr(
459 not(doctest),
460 doc = " A pessimistic estimate of the amount of energy that can be reclaimed from a fresh source (fully fueled generator\n or a fully charged battery) under the current conditions (SoH, temperature, load profile, etc)."
461 )]
462 pub full_energy: crate::uavcan::si::unit::energy::scalar_1_0::Scalar,
468 }
469 impl ::emcyphal_encoding::DataType for Source {
470 const EXTENT_BYTES: Option<u32> = None;
472 }
473 impl ::emcyphal_encoding::Message for Source {}
474 impl ::emcyphal_encoding::BufferType for Source {
475 type Buffer = ::emcyphal_encoding::StaticBuffer<16>;
476 }
477 impl Source {}
478 impl ::emcyphal_encoding::Serialize for Source {
479 fn size_bits(&self) -> usize {
480 128
481 }
482 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
483 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
484 }
485 }
486 impl ::emcyphal_encoding::Deserialize for Source {
487 fn deserialize(
488 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
489 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
490 where
491 Self: Sized,
492 {
493 Ok(Self::deserialize_zero_copy(cursor))
494 }
495 }
496 #[test]
497 fn test_layout() {
498 assert_eq!(::core::mem::size_of::<Source>() * 8, 128);
499 assert_eq!(::core::mem::offset_of!(Source, power) * 8, 0);
500 assert_eq!(::core::mem::offset_of!(Source, energy) * 8, 64);
501 assert_eq!(::core::mem::offset_of!(Source, full_energy) * 8, 96);
502 }
503 }
504 pub mod source_ts_0_1 {
505 pub struct SourceTs {
510 pub timestamp:
516 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
517 pub value: crate::reg::udral::physics::electricity::source_0_1::Source,
523 }
524 impl ::emcyphal_encoding::DataType for SourceTs {
525 const EXTENT_BYTES: Option<u32> = None;
527 }
528 impl ::emcyphal_encoding::Message for SourceTs {}
529 impl ::emcyphal_encoding::BufferType for SourceTs {
530 type Buffer = ::emcyphal_encoding::StaticBuffer<23>;
531 }
532 impl SourceTs {}
533 impl ::emcyphal_encoding::Serialize for SourceTs {
534 fn size_bits(&self) -> usize {
535 184
536 }
537 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
538 cursor.write_composite(&self.timestamp);
539 cursor.write_composite(&self.value);
540 }
541 }
542 impl ::emcyphal_encoding::Deserialize for SourceTs {
543 fn deserialize(
544 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
545 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
546 where
547 Self: Sized,
548 {
549 Ok(SourceTs {
550 timestamp: { cursor.read_composite()? },
551 value: { cursor.read_composite()? },
552 })
553 }
554 }
555 }
556 }
557 pub mod kinematics {
558 pub mod cartesian {
559 pub mod point_0_1 {
560 #[cfg_attr(
565 not(doctest),
566 doc = " Cartesian coordinates of a point in space."
567 )]
568 #[derive(
569 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
570 )]
571 #[repr(C, packed)]
572 pub struct Point {
573 pub value:
579 crate::uavcan::si::unit::length::wide_vector3_1_0::WideVector3,
580 }
581 impl ::emcyphal_encoding::DataType for Point {
582 const EXTENT_BYTES: Option<u32> = None;
584 }
585 impl ::emcyphal_encoding::Message for Point {}
586 impl ::emcyphal_encoding::BufferType for Point {
587 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
588 }
589 impl Point {}
590 impl ::emcyphal_encoding::Serialize for Point {
591 fn size_bits(&self) -> usize {
592 192
593 }
594 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
595 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
596 }
597 }
598 impl ::emcyphal_encoding::Deserialize for Point {
599 fn deserialize(
600 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
601 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
602 where
603 Self: Sized,
604 {
605 Ok(Self::deserialize_zero_copy(cursor))
606 }
607 }
608 #[test]
609 fn test_layout() {
610 assert_eq!(::core::mem::size_of::<Point>() * 8, 192);
611 assert_eq!(::core::mem::offset_of!(Point, value) * 8, 0);
612 }
613 }
614 pub mod point_state_0_1 {
615 #[cfg_attr(
620 not(doctest),
621 doc = " The kinematic state of a point, as opposed to that of a body, is devoid of rotation information.\n Therefore, the velocity is specified in the parent coordinate frame."
622 )]
623 #[derive(
624 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
625 )]
626 #[repr(C, packed)]
627 pub struct PointState {
628 pub position:
634 crate::reg::udral::physics::kinematics::cartesian::point_0_1::Point,
635 pub velocity: crate::uavcan::si::unit::velocity::vector3_1_0::Vector3,
641 }
642 impl ::emcyphal_encoding::DataType for PointState {
643 const EXTENT_BYTES: Option<u32> = None;
645 }
646 impl ::emcyphal_encoding::Message for PointState {}
647 impl ::emcyphal_encoding::BufferType for PointState {
648 type Buffer = ::emcyphal_encoding::StaticBuffer<36>;
649 }
650 impl PointState {}
651 impl ::emcyphal_encoding::Serialize for PointState {
652 fn size_bits(&self) -> usize {
653 288
654 }
655 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
656 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
657 }
658 }
659 impl ::emcyphal_encoding::Deserialize for PointState {
660 fn deserialize(
661 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
662 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
663 where
664 Self: Sized,
665 {
666 Ok(Self::deserialize_zero_copy(cursor))
667 }
668 }
669 #[test]
670 fn test_layout() {
671 assert_eq!(::core::mem::size_of::<PointState>() * 8, 288);
672 assert_eq!(::core::mem::offset_of!(PointState, position) * 8, 0);
673 assert_eq!(::core::mem::offset_of!(PointState, velocity) * 8, 192);
674 }
675 }
676 pub mod point_state_var_0_1 {
677 #[cfg_attr(not(doctest), doc = " See PointState for details.")]
682 #[derive(
683 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
684 )]
685 #[repr(C, packed)]
686 pub struct PointStateVar {
687pub position: crate::reg::udral::physics::kinematics::cartesian::point_var_0_1::PointVar,
693pub velocity: crate::reg::udral::physics::kinematics::translation::velocity3_var_0_2::Velocity3Var,
699}
700 impl ::emcyphal_encoding::DataType for PointStateVar {
701 const EXTENT_BYTES: Option<u32> = None;
703 }
704 impl ::emcyphal_encoding::Message for PointStateVar {}
705 impl ::emcyphal_encoding::BufferType for PointStateVar {
706 type Buffer = ::emcyphal_encoding::StaticBuffer<60>;
707 }
708 impl PointStateVar {}
709 impl ::emcyphal_encoding::Serialize for PointStateVar {
710 fn size_bits(&self) -> usize {
711 480
712 }
713 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
714 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
715 }
716 }
717 impl ::emcyphal_encoding::Deserialize for PointStateVar {
718 fn deserialize(
719 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
720 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
721 where
722 Self: Sized,
723 {
724 Ok(Self::deserialize_zero_copy(cursor))
725 }
726 }
727 #[test]
728 fn test_layout() {
729 assert_eq!(::core::mem::size_of::<PointStateVar>() * 8, 480);
730 assert_eq!(::core::mem::offset_of!(PointStateVar, position) * 8, 0);
731 assert_eq!(::core::mem::offset_of!(PointStateVar, velocity) * 8, 288);
732 }
733 }
734 pub mod point_state_var_ts_0_1 {
735 pub struct PointStateVarTs {
740pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
746pub value: crate::reg::udral::physics::kinematics::cartesian::point_state_var_0_1::PointStateVar,
752}
753 impl ::emcyphal_encoding::DataType for PointStateVarTs {
754 const EXTENT_BYTES: Option<u32> = None;
756 }
757 impl ::emcyphal_encoding::Message for PointStateVarTs {}
758 impl ::emcyphal_encoding::BufferType for PointStateVarTs {
759 type Buffer = ::emcyphal_encoding::StaticBuffer<67>;
760 }
761 impl PointStateVarTs {}
762 impl ::emcyphal_encoding::Serialize for PointStateVarTs {
763 fn size_bits(&self) -> usize {
764 536
765 }
766 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
767 cursor.write_composite(&self.timestamp);
768 cursor.write_composite(&self.value);
769 }
770 }
771 impl ::emcyphal_encoding::Deserialize for PointStateVarTs {
772 fn deserialize(
773 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
774 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
775 where
776 Self: Sized,
777 {
778 Ok(PointStateVarTs {
779 timestamp: { cursor.read_composite()? },
780 value: { cursor.read_composite()? },
781 })
782 }
783 }
784 }
785 pub mod point_var_0_1 {
786 #[derive(
791 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
792 )]
793 #[repr(C, packed)]
794 pub struct PointVar {
795 pub value:
801 crate::reg::udral::physics::kinematics::cartesian::point_0_1::Point,
802 #[cfg_attr(
803 not(doctest),
804 doc = " [meter^2] Upper-right triangle of the covariance matrix."
805 )]
806 pub covariance_urt: [::half::f16; 6],
812 }
813 impl ::emcyphal_encoding::DataType for PointVar {
814 const EXTENT_BYTES: Option<u32> = None;
816 }
817 impl ::emcyphal_encoding::Message for PointVar {}
818 impl ::emcyphal_encoding::BufferType for PointVar {
819 type Buffer = ::emcyphal_encoding::StaticBuffer<36>;
820 }
821 impl PointVar {}
822 impl ::emcyphal_encoding::Serialize for PointVar {
823 fn size_bits(&self) -> usize {
824 288
825 }
826 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
827 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
828 }
829 }
830 impl ::emcyphal_encoding::Deserialize for PointVar {
831 fn deserialize(
832 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
833 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
834 where
835 Self: Sized,
836 {
837 Ok(Self::deserialize_zero_copy(cursor))
838 }
839 }
840 #[test]
841 fn test_layout() {
842 assert_eq!(::core::mem::size_of::<PointVar>() * 8, 288);
843 assert_eq!(::core::mem::offset_of!(PointVar, value) * 8, 0);
844 assert_eq!(::core::mem::offset_of!(PointVar, covariance_urt) * 8, 192);
845 }
846 }
847 pub mod pose_0_1 {
848 #[derive(
853 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
854 )]
855 #[repr(C, packed)]
856 pub struct Pose {
857 pub position:
863 crate::reg::udral::physics::kinematics::cartesian::point_0_1::Point,
864 pub orientation:
870 crate::uavcan::si::unit::angle::quaternion_1_0::Quaternion,
871 }
872 impl ::emcyphal_encoding::DataType for Pose {
873 const EXTENT_BYTES: Option<u32> = None;
875 }
876 impl ::emcyphal_encoding::Message for Pose {}
877 impl ::emcyphal_encoding::BufferType for Pose {
878 type Buffer = ::emcyphal_encoding::StaticBuffer<40>;
879 }
880 impl Pose {}
881 impl ::emcyphal_encoding::Serialize for Pose {
882 fn size_bits(&self) -> usize {
883 320
884 }
885 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
886 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
887 }
888 }
889 impl ::emcyphal_encoding::Deserialize for Pose {
890 fn deserialize(
891 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
892 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
893 where
894 Self: Sized,
895 {
896 Ok(Self::deserialize_zero_copy(cursor))
897 }
898 }
899 #[test]
900 fn test_layout() {
901 assert_eq!(::core::mem::size_of::<Pose>() * 8, 320);
902 assert_eq!(::core::mem::offset_of!(Pose, position) * 8, 0);
903 assert_eq!(::core::mem::offset_of!(Pose, orientation) * 8, 192);
904 }
905 }
906 pub mod pose_var_0_1 {
907 #[derive(
912 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
913 )]
914 #[repr(C, packed)]
915 pub struct PoseVar {
916 pub value:
922 crate::reg::udral::physics::kinematics::cartesian::pose_0_1::Pose,
923 #[cfg_attr(
924 not(doctest),
925 doc = " Upper-right triangle of the covariance matrix:\n\n [parent frame] [child (body) frame]\n translation along axis rotation about axis\n X Y Z X Y Z\n +-----------------------------------------------\n X position |\n Y position | m^2 m*rad\n Z position |\n X rotation |\n Y rotation | rad^2\n Z rotation |"
926 )]
927 pub covariance_urt: [::half::f16; 21],
933 }
934 impl ::emcyphal_encoding::DataType for PoseVar {
935 const EXTENT_BYTES: Option<u32> = None;
937 }
938 impl ::emcyphal_encoding::Message for PoseVar {}
939 impl ::emcyphal_encoding::BufferType for PoseVar {
940 type Buffer = ::emcyphal_encoding::StaticBuffer<82>;
941 }
942 impl PoseVar {}
943 impl ::emcyphal_encoding::Serialize for PoseVar {
944 fn size_bits(&self) -> usize {
945 656
946 }
947 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
948 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
949 }
950 }
951 impl ::emcyphal_encoding::Deserialize for PoseVar {
952 fn deserialize(
953 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
954 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
955 where
956 Self: Sized,
957 {
958 Ok(Self::deserialize_zero_copy(cursor))
959 }
960 }
961 #[test]
962 fn test_layout() {
963 assert_eq!(::core::mem::size_of::<PoseVar>() * 8, 656);
964 assert_eq!(::core::mem::offset_of!(PoseVar, value) * 8, 0);
965 assert_eq!(::core::mem::offset_of!(PoseVar, covariance_urt) * 8, 320);
966 }
967 }
968 pub mod pose_var_ts_0_1 {
969 pub struct PoseVarTs {
974pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
980pub value: crate::reg::udral::physics::kinematics::cartesian::pose_var_0_1::PoseVar,
986}
987 impl ::emcyphal_encoding::DataType for PoseVarTs {
988 const EXTENT_BYTES: Option<u32> = None;
990 }
991 impl ::emcyphal_encoding::Message for PoseVarTs {}
992 impl ::emcyphal_encoding::BufferType for PoseVarTs {
993 type Buffer = ::emcyphal_encoding::StaticBuffer<89>;
994 }
995 impl PoseVarTs {}
996 impl ::emcyphal_encoding::Serialize for PoseVarTs {
997 fn size_bits(&self) -> usize {
998 712
999 }
1000 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1001 cursor.write_composite(&self.timestamp);
1002 cursor.write_composite(&self.value);
1003 }
1004 }
1005 impl ::emcyphal_encoding::Deserialize for PoseVarTs {
1006 fn deserialize(
1007 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1008 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1009 where
1010 Self: Sized,
1011 {
1012 Ok(PoseVarTs {
1013 timestamp: { cursor.read_composite()? },
1014 value: { cursor.read_composite()? },
1015 })
1016 }
1017 }
1018 }
1019 pub mod state_0_1 {
1020 #[cfg_attr(
1025 not(doctest),
1026 doc = " First-order kinematic state of a body in space: pose and twist.\n The pose defines a coordinate system transformation from the parent frame to the child frame.\n The twist is specified in the child frame (body frame)."
1027 )]
1028 #[derive(
1029 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1030 )]
1031 #[repr(C, packed)]
1032 pub struct State {
1033 pub pose:
1039 crate::reg::udral::physics::kinematics::cartesian::pose_0_1::Pose,
1040 pub twist:
1046 crate::reg::udral::physics::kinematics::cartesian::twist_0_1::Twist,
1047 }
1048 impl ::emcyphal_encoding::DataType for State {
1049 const EXTENT_BYTES: Option<u32> = None;
1051 }
1052 impl ::emcyphal_encoding::Message for State {}
1053 impl ::emcyphal_encoding::BufferType for State {
1054 type Buffer = ::emcyphal_encoding::StaticBuffer<64>;
1055 }
1056 impl State {}
1057 impl ::emcyphal_encoding::Serialize for State {
1058 fn size_bits(&self) -> usize {
1059 512
1060 }
1061 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1062 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1063 }
1064 }
1065 impl ::emcyphal_encoding::Deserialize for State {
1066 fn deserialize(
1067 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1068 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1069 where
1070 Self: Sized,
1071 {
1072 Ok(Self::deserialize_zero_copy(cursor))
1073 }
1074 }
1075 #[test]
1076 fn test_layout() {
1077 assert_eq!(::core::mem::size_of::<State>() * 8, 512);
1078 assert_eq!(::core::mem::offset_of!(State, pose) * 8, 0);
1079 assert_eq!(::core::mem::offset_of!(State, twist) * 8, 320);
1080 }
1081 }
1082 pub mod state_var_0_1 {
1083 #[cfg_attr(
1088 not(doctest),
1089 doc = " See State for details. This type extends it with covariance matrices."
1090 )]
1091 #[derive(
1092 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1093 )]
1094 #[repr(C, packed)]
1095 pub struct StateVar {
1096pub pose: crate::reg::udral::physics::kinematics::cartesian::pose_var_0_1::PoseVar,
1102pub twist: crate::reg::udral::physics::kinematics::cartesian::twist_var_0_1::TwistVar,
1108}
1109 impl ::emcyphal_encoding::DataType for StateVar {
1110 const EXTENT_BYTES: Option<u32> = None;
1112 }
1113 impl ::emcyphal_encoding::Message for StateVar {}
1114 impl ::emcyphal_encoding::BufferType for StateVar {
1115 type Buffer = ::emcyphal_encoding::StaticBuffer<148>;
1116 }
1117 impl StateVar {}
1118 impl ::emcyphal_encoding::Serialize for StateVar {
1119 fn size_bits(&self) -> usize {
1120 1184
1121 }
1122 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1123 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1124 }
1125 }
1126 impl ::emcyphal_encoding::Deserialize for StateVar {
1127 fn deserialize(
1128 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1129 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1130 where
1131 Self: Sized,
1132 {
1133 Ok(Self::deserialize_zero_copy(cursor))
1134 }
1135 }
1136 #[test]
1137 fn test_layout() {
1138 assert_eq!(::core::mem::size_of::<StateVar>() * 8, 1184);
1139 assert_eq!(::core::mem::offset_of!(StateVar, pose) * 8, 0);
1140 assert_eq!(::core::mem::offset_of!(StateVar, twist) * 8, 656);
1141 }
1142 }
1143 pub mod state_var_ts_0_1 {
1144 pub struct StateVarTs {
1149pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
1155pub value: crate::reg::udral::physics::kinematics::cartesian::state_var_0_1::StateVar,
1161}
1162 impl ::emcyphal_encoding::DataType for StateVarTs {
1163 const EXTENT_BYTES: Option<u32> = None;
1165 }
1166 impl ::emcyphal_encoding::Message for StateVarTs {}
1167 impl ::emcyphal_encoding::BufferType for StateVarTs {
1168 type Buffer = ::emcyphal_encoding::StaticBuffer<155>;
1169 }
1170 impl StateVarTs {}
1171 impl ::emcyphal_encoding::Serialize for StateVarTs {
1172 fn size_bits(&self) -> usize {
1173 1240
1174 }
1175 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1176 cursor.write_composite(&self.timestamp);
1177 cursor.write_composite(&self.value);
1178 }
1179 }
1180 impl ::emcyphal_encoding::Deserialize for StateVarTs {
1181 fn deserialize(
1182 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1183 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1184 where
1185 Self: Sized,
1186 {
1187 Ok(StateVarTs {
1188 timestamp: { cursor.read_composite()? },
1189 value: { cursor.read_composite()? },
1190 })
1191 }
1192 }
1193 }
1194 pub mod twist_0_1 {
1195 #[cfg_attr(
1200 not(doctest),
1201 doc = " Motion of a rigid body in 3D space defined in the body frame."
1202 )]
1203 #[derive(
1204 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1205 )]
1206 #[repr(C, packed)]
1207 pub struct Twist {
1208 #[cfg_attr(not(doctest), doc = " Linear velocity in the body frame.")]
1209 pub linear: crate::uavcan::si::unit::velocity::vector3_1_0::Vector3,
1215 #[cfg_attr(
1216 not(doctest),
1217 doc = " Angular velocity about the fixed axes of the body frame (extrinsic)."
1218 )]
1219 pub angular:
1225 crate::uavcan::si::unit::angular_velocity::vector3_1_0::Vector3,
1226 }
1227 impl ::emcyphal_encoding::DataType for Twist {
1228 const EXTENT_BYTES: Option<u32> = None;
1230 }
1231 impl ::emcyphal_encoding::Message for Twist {}
1232 impl ::emcyphal_encoding::BufferType for Twist {
1233 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
1234 }
1235 impl Twist {}
1236 impl ::emcyphal_encoding::Serialize for Twist {
1237 fn size_bits(&self) -> usize {
1238 192
1239 }
1240 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1241 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1242 }
1243 }
1244 impl ::emcyphal_encoding::Deserialize for Twist {
1245 fn deserialize(
1246 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1247 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1248 where
1249 Self: Sized,
1250 {
1251 Ok(Self::deserialize_zero_copy(cursor))
1252 }
1253 }
1254 #[test]
1255 fn test_layout() {
1256 assert_eq!(::core::mem::size_of::<Twist>() * 8, 192);
1257 assert_eq!(::core::mem::offset_of!(Twist, linear) * 8, 0);
1258 assert_eq!(::core::mem::offset_of!(Twist, angular) * 8, 96);
1259 }
1260 }
1261 pub mod twist_var_0_1 {
1262 #[derive(
1267 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1268 )]
1269 #[repr(C, packed)]
1270 pub struct TwistVar {
1271 pub value:
1277 crate::reg::udral::physics::kinematics::cartesian::twist_0_1::Twist,
1278 #[cfg_attr(
1279 not(doctest),
1280 doc = " Upper-right triangle of the covariance matrix:\n\n translation along axis rotation about axis\n X Y Z X Y Z\n +----------------------------------------------\n X velocity |\n Y velocity | (m/s)^2 (m*rad)/s^2\n Z velocity |\n X angular velocity |\n Y angular velocity | (rad/s)^2\n Z angular velocity |"
1281 )]
1282 pub covariance_urt: [::half::f16; 21],
1288 }
1289 impl ::emcyphal_encoding::DataType for TwistVar {
1290 const EXTENT_BYTES: Option<u32> = None;
1292 }
1293 impl ::emcyphal_encoding::Message for TwistVar {}
1294 impl ::emcyphal_encoding::BufferType for TwistVar {
1295 type Buffer = ::emcyphal_encoding::StaticBuffer<66>;
1296 }
1297 impl TwistVar {}
1298 impl ::emcyphal_encoding::Serialize for TwistVar {
1299 fn size_bits(&self) -> usize {
1300 528
1301 }
1302 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1303 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1304 }
1305 }
1306 impl ::emcyphal_encoding::Deserialize for TwistVar {
1307 fn deserialize(
1308 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1309 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1310 where
1311 Self: Sized,
1312 {
1313 Ok(Self::deserialize_zero_copy(cursor))
1314 }
1315 }
1316 #[test]
1317 fn test_layout() {
1318 assert_eq!(::core::mem::size_of::<TwistVar>() * 8, 528);
1319 assert_eq!(::core::mem::offset_of!(TwistVar, value) * 8, 0);
1320 assert_eq!(::core::mem::offset_of!(TwistVar, covariance_urt) * 8, 192);
1321 }
1322 }
1323 pub mod twist_var_ts_0_1 {
1324 pub struct TwistVarTs {
1329pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
1335pub value: crate::reg::udral::physics::kinematics::cartesian::twist_var_0_1::TwistVar,
1341}
1342 impl ::emcyphal_encoding::DataType for TwistVarTs {
1343 const EXTENT_BYTES: Option<u32> = None;
1345 }
1346 impl ::emcyphal_encoding::Message for TwistVarTs {}
1347 impl ::emcyphal_encoding::BufferType for TwistVarTs {
1348 type Buffer = ::emcyphal_encoding::StaticBuffer<73>;
1349 }
1350 impl TwistVarTs {}
1351 impl ::emcyphal_encoding::Serialize for TwistVarTs {
1352 fn size_bits(&self) -> usize {
1353 584
1354 }
1355 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1356 cursor.write_composite(&self.timestamp);
1357 cursor.write_composite(&self.value);
1358 }
1359 }
1360 impl ::emcyphal_encoding::Deserialize for TwistVarTs {
1361 fn deserialize(
1362 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1363 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1364 where
1365 Self: Sized,
1366 {
1367 Ok(TwistVarTs {
1368 timestamp: { cursor.read_composite()? },
1369 value: { cursor.read_composite()? },
1370 })
1371 }
1372 }
1373 }
1374 }
1375 pub mod geodetic {
1376 pub mod point_0_1 {
1377 #[cfg_attr(
1382 not(doctest),
1383 doc = " Geodetic position: latitude, longitude, and altitude.\n The order is chosen to match the axis ordering of the NED frame.\n The size and layout of this structure is equal to the Cartesian pose type."
1384 )]
1385 #[derive(
1386 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1387 )]
1388 #[repr(C, packed)]
1389 pub struct Point {
1390 #[cfg_attr(not(doctest), doc = " [radian]")]
1391 pub latitude: f64,
1397 #[cfg_attr(not(doctest), doc = " [radian]")]
1398 pub longitude: f64,
1404 #[cfg_attr(
1405 not(doctest),
1406 doc = " Distance between the local mean sea level (MSL) and the focal point of the antenna. Positive altitude above the MSL."
1407 )]
1408 pub altitude:
1414 crate::uavcan::si::unit::length::wide_scalar_1_0::WideScalar,
1415 }
1416 impl ::emcyphal_encoding::DataType for Point {
1417 const EXTENT_BYTES: Option<u32> = None;
1419 }
1420 impl ::emcyphal_encoding::Message for Point {}
1421 impl ::emcyphal_encoding::BufferType for Point {
1422 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
1423 }
1424 impl Point {}
1425 impl ::emcyphal_encoding::Serialize for Point {
1426 fn size_bits(&self) -> usize {
1427 192
1428 }
1429 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1430 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1431 }
1432 }
1433 impl ::emcyphal_encoding::Deserialize for Point {
1434 fn deserialize(
1435 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1436 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1437 where
1438 Self: Sized,
1439 {
1440 Ok(Self::deserialize_zero_copy(cursor))
1441 }
1442 }
1443 #[test]
1444 fn test_layout() {
1445 assert_eq!(::core::mem::size_of::<Point>() * 8, 192);
1446 assert_eq!(::core::mem::offset_of!(Point, latitude) * 8, 0);
1447 assert_eq!(::core::mem::offset_of!(Point, longitude) * 8, 64);
1448 assert_eq!(::core::mem::offset_of!(Point, altitude) * 8, 128);
1449 }
1450 }
1451 pub mod point_state_0_1 {
1452 #[cfg_attr(
1457 not(doctest),
1458 doc = " The kinematic state of a point, as opposed to that of a body, is devoid of rotation information.\n Therefore, the velocity is specified in the parent coordinate frame."
1459 )]
1460 #[derive(
1461 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1462 )]
1463 #[repr(C, packed)]
1464 pub struct PointState {
1465 pub position:
1471 crate::reg::udral::physics::kinematics::geodetic::point_0_1::Point,
1472 pub velocity: crate::uavcan::si::unit::velocity::vector3_1_0::Vector3,
1478 }
1479 impl ::emcyphal_encoding::DataType for PointState {
1480 const EXTENT_BYTES: Option<u32> = None;
1482 }
1483 impl ::emcyphal_encoding::Message for PointState {}
1484 impl ::emcyphal_encoding::BufferType for PointState {
1485 type Buffer = ::emcyphal_encoding::StaticBuffer<36>;
1486 }
1487 impl PointState {}
1488 impl ::emcyphal_encoding::Serialize for PointState {
1489 fn size_bits(&self) -> usize {
1490 288
1491 }
1492 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1493 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1494 }
1495 }
1496 impl ::emcyphal_encoding::Deserialize for PointState {
1497 fn deserialize(
1498 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1499 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1500 where
1501 Self: Sized,
1502 {
1503 Ok(Self::deserialize_zero_copy(cursor))
1504 }
1505 }
1506 #[test]
1507 fn test_layout() {
1508 assert_eq!(::core::mem::size_of::<PointState>() * 8, 288);
1509 assert_eq!(::core::mem::offset_of!(PointState, position) * 8, 0);
1510 assert_eq!(::core::mem::offset_of!(PointState, velocity) * 8, 192);
1511 }
1512 }
1513 pub mod point_state_var_0_1 {
1514 #[cfg_attr(not(doctest), doc = " See PointState for details.")]
1519 #[derive(
1520 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1521 )]
1522 #[repr(C, packed)]
1523 pub struct PointStateVar {
1524pub position: crate::reg::udral::physics::kinematics::geodetic::point_var_0_1::PointVar,
1530pub velocity: crate::reg::udral::physics::kinematics::translation::velocity3_var_0_2::Velocity3Var,
1536}
1537 impl ::emcyphal_encoding::DataType for PointStateVar {
1538 const EXTENT_BYTES: Option<u32> = None;
1540 }
1541 impl ::emcyphal_encoding::Message for PointStateVar {}
1542 impl ::emcyphal_encoding::BufferType for PointStateVar {
1543 type Buffer = ::emcyphal_encoding::StaticBuffer<60>;
1544 }
1545 impl PointStateVar {}
1546 impl ::emcyphal_encoding::Serialize for PointStateVar {
1547 fn size_bits(&self) -> usize {
1548 480
1549 }
1550 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1551 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1552 }
1553 }
1554 impl ::emcyphal_encoding::Deserialize for PointStateVar {
1555 fn deserialize(
1556 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1557 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1558 where
1559 Self: Sized,
1560 {
1561 Ok(Self::deserialize_zero_copy(cursor))
1562 }
1563 }
1564 #[test]
1565 fn test_layout() {
1566 assert_eq!(::core::mem::size_of::<PointStateVar>() * 8, 480);
1567 assert_eq!(::core::mem::offset_of!(PointStateVar, position) * 8, 0);
1568 assert_eq!(::core::mem::offset_of!(PointStateVar, velocity) * 8, 288);
1569 }
1570 }
1571 pub mod point_state_var_ts_0_1 {
1572 pub struct PointStateVarTs {
1577pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
1583pub value: crate::reg::udral::physics::kinematics::geodetic::point_state_var_0_1::PointStateVar,
1589}
1590 impl ::emcyphal_encoding::DataType for PointStateVarTs {
1591 const EXTENT_BYTES: Option<u32> = None;
1593 }
1594 impl ::emcyphal_encoding::Message for PointStateVarTs {}
1595 impl ::emcyphal_encoding::BufferType for PointStateVarTs {
1596 type Buffer = ::emcyphal_encoding::StaticBuffer<67>;
1597 }
1598 impl PointStateVarTs {}
1599 impl ::emcyphal_encoding::Serialize for PointStateVarTs {
1600 fn size_bits(&self) -> usize {
1601 536
1602 }
1603 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1604 cursor.write_composite(&self.timestamp);
1605 cursor.write_composite(&self.value);
1606 }
1607 }
1608 impl ::emcyphal_encoding::Deserialize for PointStateVarTs {
1609 fn deserialize(
1610 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1611 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1612 where
1613 Self: Sized,
1614 {
1615 Ok(PointStateVarTs {
1616 timestamp: { cursor.read_composite()? },
1617 value: { cursor.read_composite()? },
1618 })
1619 }
1620 }
1621 }
1622 pub mod point_var_0_1 {
1623 #[derive(
1628 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1629 )]
1630 #[repr(C, packed)]
1631 pub struct PointVar {
1632 pub value:
1638 crate::reg::udral::physics::kinematics::geodetic::point_0_1::Point,
1639 #[cfg_attr(
1640 not(doctest),
1641 doc = " [meter^2]\n Upper-right triangle of the covariance matrix.\n The position covariance is defined relative to a tangential plane through the specified latitude/longitude.\n Element ordering: latitude, longitude, altitude. It is chosen to match the axis ordering of the NED frame."
1642 )]
1643 pub covariance_urt: [::half::f16; 6],
1649 }
1650 impl ::emcyphal_encoding::DataType for PointVar {
1651 const EXTENT_BYTES: Option<u32> = None;
1653 }
1654 impl ::emcyphal_encoding::Message for PointVar {}
1655 impl ::emcyphal_encoding::BufferType for PointVar {
1656 type Buffer = ::emcyphal_encoding::StaticBuffer<36>;
1657 }
1658 impl PointVar {}
1659 impl ::emcyphal_encoding::Serialize for PointVar {
1660 fn size_bits(&self) -> usize {
1661 288
1662 }
1663 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1664 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1665 }
1666 }
1667 impl ::emcyphal_encoding::Deserialize for PointVar {
1668 fn deserialize(
1669 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1670 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1671 where
1672 Self: Sized,
1673 {
1674 Ok(Self::deserialize_zero_copy(cursor))
1675 }
1676 }
1677 #[test]
1678 fn test_layout() {
1679 assert_eq!(::core::mem::size_of::<PointVar>() * 8, 288);
1680 assert_eq!(::core::mem::offset_of!(PointVar, value) * 8, 0);
1681 assert_eq!(::core::mem::offset_of!(PointVar, covariance_urt) * 8, 192);
1682 }
1683 }
1684 pub mod pose_0_1 {
1685 #[cfg_attr(
1690 not(doctest),
1691 doc = " Zero rotation is the state where the axes of the body frame are aligned with the axes of the local NED frame:\n X points north, Y points east, Z points down."
1692 )]
1693 #[derive(
1694 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1695 )]
1696 #[repr(C, packed)]
1697 pub struct Pose {
1698 pub position:
1704 crate::reg::udral::physics::kinematics::geodetic::point_0_1::Point,
1705 pub orientation:
1711 crate::uavcan::si::unit::angle::quaternion_1_0::Quaternion,
1712 }
1713 impl ::emcyphal_encoding::DataType for Pose {
1714 const EXTENT_BYTES: Option<u32> = None;
1716 }
1717 impl ::emcyphal_encoding::Message for Pose {}
1718 impl ::emcyphal_encoding::BufferType for Pose {
1719 type Buffer = ::emcyphal_encoding::StaticBuffer<40>;
1720 }
1721 impl Pose {}
1722 impl ::emcyphal_encoding::Serialize for Pose {
1723 fn size_bits(&self) -> usize {
1724 320
1725 }
1726 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1727 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1728 }
1729 }
1730 impl ::emcyphal_encoding::Deserialize for Pose {
1731 fn deserialize(
1732 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1733 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1734 where
1735 Self: Sized,
1736 {
1737 Ok(Self::deserialize_zero_copy(cursor))
1738 }
1739 }
1740 #[test]
1741 fn test_layout() {
1742 assert_eq!(::core::mem::size_of::<Pose>() * 8, 320);
1743 assert_eq!(::core::mem::offset_of!(Pose, position) * 8, 0);
1744 assert_eq!(::core::mem::offset_of!(Pose, orientation) * 8, 192);
1745 }
1746 }
1747 pub mod pose_var_0_1 {
1748 #[derive(
1753 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1754 )]
1755 #[repr(C, packed)]
1756 pub struct PoseVar {
1757 pub value:
1763 crate::reg::udral::physics::kinematics::geodetic::pose_0_1::Pose,
1764 #[cfg_attr(
1765 not(doctest),
1766 doc = " Upper-right triangle of the covariance matrix:\n\n [parent frame] [child (body) frame]\n translation along axis rotation about axis\n X Y Z X Y Z\n +-----------------------------------------------\n X position |\n Y position | m^2 m*rad\n Z position |\n X rotation |\n Y rotation | rad^2\n Z rotation |"
1767 )]
1768 pub covariance_urt: [::half::f16; 21],
1774 }
1775 impl ::emcyphal_encoding::DataType for PoseVar {
1776 const EXTENT_BYTES: Option<u32> = None;
1778 }
1779 impl ::emcyphal_encoding::Message for PoseVar {}
1780 impl ::emcyphal_encoding::BufferType for PoseVar {
1781 type Buffer = ::emcyphal_encoding::StaticBuffer<82>;
1782 }
1783 impl PoseVar {}
1784 impl ::emcyphal_encoding::Serialize for PoseVar {
1785 fn size_bits(&self) -> usize {
1786 656
1787 }
1788 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1789 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1790 }
1791 }
1792 impl ::emcyphal_encoding::Deserialize for PoseVar {
1793 fn deserialize(
1794 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1795 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1796 where
1797 Self: Sized,
1798 {
1799 Ok(Self::deserialize_zero_copy(cursor))
1800 }
1801 }
1802 #[test]
1803 fn test_layout() {
1804 assert_eq!(::core::mem::size_of::<PoseVar>() * 8, 656);
1805 assert_eq!(::core::mem::offset_of!(PoseVar, value) * 8, 0);
1806 assert_eq!(::core::mem::offset_of!(PoseVar, covariance_urt) * 8, 320);
1807 }
1808 }
1809 pub mod state_0_1 {
1810 #[cfg_attr(
1815 not(doctest),
1816 doc = " First-order kinematic state of a body near the surface of a planet.\n The pose defines a coordinate system transformation from the parent frame to the child frame.\n The twist is specified in the child frame (body frame)."
1817 )]
1818 #[derive(
1819 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1820 )]
1821 #[repr(C, packed)]
1822 pub struct State {
1823 pub pose:
1829 crate::reg::udral::physics::kinematics::geodetic::pose_0_1::Pose,
1830 pub twist:
1836 crate::reg::udral::physics::kinematics::cartesian::twist_0_1::Twist,
1837 }
1838 impl ::emcyphal_encoding::DataType for State {
1839 const EXTENT_BYTES: Option<u32> = None;
1841 }
1842 impl ::emcyphal_encoding::Message for State {}
1843 impl ::emcyphal_encoding::BufferType for State {
1844 type Buffer = ::emcyphal_encoding::StaticBuffer<64>;
1845 }
1846 impl State {}
1847 impl ::emcyphal_encoding::Serialize for State {
1848 fn size_bits(&self) -> usize {
1849 512
1850 }
1851 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1852 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1853 }
1854 }
1855 impl ::emcyphal_encoding::Deserialize for State {
1856 fn deserialize(
1857 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1858 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1859 where
1860 Self: Sized,
1861 {
1862 Ok(Self::deserialize_zero_copy(cursor))
1863 }
1864 }
1865 #[test]
1866 fn test_layout() {
1867 assert_eq!(::core::mem::size_of::<State>() * 8, 512);
1868 assert_eq!(::core::mem::offset_of!(State, pose) * 8, 0);
1869 assert_eq!(::core::mem::offset_of!(State, twist) * 8, 320);
1870 }
1871 }
1872 pub mod state_var_0_1 {
1873 #[cfg_attr(
1878 not(doctest),
1879 doc = " See State for details. This type extends it with covariance matrices."
1880 )]
1881 #[derive(
1882 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1883 )]
1884 #[repr(C, packed)]
1885 pub struct StateVar {
1886pub pose: crate::reg::udral::physics::kinematics::geodetic::pose_var_0_1::PoseVar,
1892pub twist: crate::reg::udral::physics::kinematics::cartesian::twist_var_0_1::TwistVar,
1898}
1899 impl ::emcyphal_encoding::DataType for StateVar {
1900 const EXTENT_BYTES: Option<u32> = None;
1902 }
1903 impl ::emcyphal_encoding::Message for StateVar {}
1904 impl ::emcyphal_encoding::BufferType for StateVar {
1905 type Buffer = ::emcyphal_encoding::StaticBuffer<148>;
1906 }
1907 impl StateVar {}
1908 impl ::emcyphal_encoding::Serialize for StateVar {
1909 fn size_bits(&self) -> usize {
1910 1184
1911 }
1912 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1913 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
1914 }
1915 }
1916 impl ::emcyphal_encoding::Deserialize for StateVar {
1917 fn deserialize(
1918 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1919 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1920 where
1921 Self: Sized,
1922 {
1923 Ok(Self::deserialize_zero_copy(cursor))
1924 }
1925 }
1926 #[test]
1927 fn test_layout() {
1928 assert_eq!(::core::mem::size_of::<StateVar>() * 8, 1184);
1929 assert_eq!(::core::mem::offset_of!(StateVar, pose) * 8, 0);
1930 assert_eq!(::core::mem::offset_of!(StateVar, twist) * 8, 656);
1931 }
1932 }
1933 pub mod state_var_ts_0_1 {
1934 pub struct StateVarTs {
1939pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
1945pub value: crate::reg::udral::physics::kinematics::geodetic::state_var_0_1::StateVar,
1951}
1952 impl ::emcyphal_encoding::DataType for StateVarTs {
1953 const EXTENT_BYTES: Option<u32> = None;
1955 }
1956 impl ::emcyphal_encoding::Message for StateVarTs {}
1957 impl ::emcyphal_encoding::BufferType for StateVarTs {
1958 type Buffer = ::emcyphal_encoding::StaticBuffer<155>;
1959 }
1960 impl StateVarTs {}
1961 impl ::emcyphal_encoding::Serialize for StateVarTs {
1962 fn size_bits(&self) -> usize {
1963 1240
1964 }
1965 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
1966 cursor.write_composite(&self.timestamp);
1967 cursor.write_composite(&self.value);
1968 }
1969 }
1970 impl ::emcyphal_encoding::Deserialize for StateVarTs {
1971 fn deserialize(
1972 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
1973 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
1974 where
1975 Self: Sized,
1976 {
1977 Ok(StateVarTs {
1978 timestamp: { cursor.read_composite()? },
1979 value: { cursor.read_composite()? },
1980 })
1981 }
1982 }
1983 }
1984 }
1985 pub mod rotation {
1986 pub mod planar_0_1 {
1987 #[cfg_attr(not(doctest), doc = " Rotation about an axis.")]
1992 #[derive(
1993 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
1994 )]
1995 #[repr(C, packed)]
1996 pub struct Planar {
1997 pub angular_position:
2003 crate::uavcan::si::unit::angle::scalar_1_0::Scalar,
2004 pub angular_velocity:
2010 crate::uavcan::si::unit::angular_velocity::scalar_1_0::Scalar,
2011 pub angular_acceleration:
2017 crate::uavcan::si::unit::angular_acceleration::scalar_1_0::Scalar,
2018 }
2019 impl ::emcyphal_encoding::DataType for Planar {
2020 const EXTENT_BYTES: Option<u32> = None;
2022 }
2023 impl ::emcyphal_encoding::Message for Planar {}
2024 impl ::emcyphal_encoding::BufferType for Planar {
2025 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
2026 }
2027 impl Planar {}
2028 impl ::emcyphal_encoding::Serialize for Planar {
2029 fn size_bits(&self) -> usize {
2030 96
2031 }
2032 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2033 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2034 }
2035 }
2036 impl ::emcyphal_encoding::Deserialize for Planar {
2037 fn deserialize(
2038 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2039 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2040 where
2041 Self: Sized,
2042 {
2043 Ok(Self::deserialize_zero_copy(cursor))
2044 }
2045 }
2046 #[test]
2047 fn test_layout() {
2048 assert_eq!(::core::mem::size_of::<Planar>() * 8, 96);
2049 assert_eq!(::core::mem::offset_of!(Planar, angular_position) * 8, 0);
2050 assert_eq!(::core::mem::offset_of!(Planar, angular_velocity) * 8, 32);
2051 assert_eq!(
2052 ::core::mem::offset_of!(Planar, angular_acceleration) * 8,
2053 64
2054 );
2055 }
2056 }
2057 pub mod planar_ts_0_1 {
2058 pub struct PlanarTs {
2063pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
2069pub value: crate::reg::udral::physics::kinematics::rotation::planar_0_1::Planar,
2075}
2076 impl ::emcyphal_encoding::DataType for PlanarTs {
2077 const EXTENT_BYTES: Option<u32> = None;
2079 }
2080 impl ::emcyphal_encoding::Message for PlanarTs {}
2081 impl ::emcyphal_encoding::BufferType for PlanarTs {
2082 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
2083 }
2084 impl PlanarTs {}
2085 impl ::emcyphal_encoding::Serialize for PlanarTs {
2086 fn size_bits(&self) -> usize {
2087 152
2088 }
2089 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2090 cursor.write_composite(&self.timestamp);
2091 cursor.write_composite(&self.value);
2092 }
2093 }
2094 impl ::emcyphal_encoding::Deserialize for PlanarTs {
2095 fn deserialize(
2096 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2097 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2098 where
2099 Self: Sized,
2100 {
2101 Ok(PlanarTs {
2102 timestamp: { cursor.read_composite()? },
2103 value: { cursor.read_composite()? },
2104 })
2105 }
2106 }
2107 }
2108 }
2109 pub mod translation {
2110 pub mod linear_0_1 {
2111 #[cfg_attr(not(doctest), doc = " Movement along an axis.")]
2116 #[derive(
2117 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
2118 )]
2119 #[repr(C, packed)]
2120 pub struct Linear {
2121 pub position: crate::uavcan::si::unit::length::scalar_1_0::Scalar,
2127 pub velocity: crate::uavcan::si::unit::velocity::scalar_1_0::Scalar,
2133 pub acceleration:
2139 crate::uavcan::si::unit::acceleration::scalar_1_0::Scalar,
2140 }
2141 impl ::emcyphal_encoding::DataType for Linear {
2142 const EXTENT_BYTES: Option<u32> = None;
2144 }
2145 impl ::emcyphal_encoding::Message for Linear {}
2146 impl ::emcyphal_encoding::BufferType for Linear {
2147 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
2148 }
2149 impl Linear {}
2150 impl ::emcyphal_encoding::Serialize for Linear {
2151 fn size_bits(&self) -> usize {
2152 96
2153 }
2154 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2155 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2156 }
2157 }
2158 impl ::emcyphal_encoding::Deserialize for Linear {
2159 fn deserialize(
2160 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2161 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2162 where
2163 Self: Sized,
2164 {
2165 Ok(Self::deserialize_zero_copy(cursor))
2166 }
2167 }
2168 #[test]
2169 fn test_layout() {
2170 assert_eq!(::core::mem::size_of::<Linear>() * 8, 96);
2171 assert_eq!(::core::mem::offset_of!(Linear, position) * 8, 0);
2172 assert_eq!(::core::mem::offset_of!(Linear, velocity) * 8, 32);
2173 assert_eq!(::core::mem::offset_of!(Linear, acceleration) * 8, 64);
2174 }
2175 }
2176 pub mod linear_ts_0_1 {
2177 pub struct LinearTs {
2182pub timestamp: crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
2188pub value: crate::reg::udral::physics::kinematics::translation::linear_0_1::Linear,
2194}
2195 impl ::emcyphal_encoding::DataType for LinearTs {
2196 const EXTENT_BYTES: Option<u32> = None;
2198 }
2199 impl ::emcyphal_encoding::Message for LinearTs {}
2200 impl ::emcyphal_encoding::BufferType for LinearTs {
2201 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
2202 }
2203 impl LinearTs {}
2204 impl ::emcyphal_encoding::Serialize for LinearTs {
2205 fn size_bits(&self) -> usize {
2206 152
2207 }
2208 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2209 cursor.write_composite(&self.timestamp);
2210 cursor.write_composite(&self.value);
2211 }
2212 }
2213 impl ::emcyphal_encoding::Deserialize for LinearTs {
2214 fn deserialize(
2215 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2216 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2217 where
2218 Self: Sized,
2219 {
2220 Ok(LinearTs {
2221 timestamp: { cursor.read_composite()? },
2222 value: { cursor.read_composite()? },
2223 })
2224 }
2225 }
2226 }
2227 pub mod linear_var_ts_0_1 {
2228 #[cfg_attr(
2233 not(doctest),
2234 doc = " This is a structural subtype of LinearTs.\n Use best guess if the error variance is unknown."
2235 )]
2236 pub struct LinearVarTs {
2237pub value: crate::reg::udral::physics::kinematics::translation::linear_ts_0_1::LinearTs,
2243#[cfg_attr(not(doctest), doc = " [meter^2]")]
2244pub position_error_variance: ::half::f16,
2250#[cfg_attr(not(doctest), doc = " [(meter/second)^2]")]
2251pub velocity_error_variance: ::half::f16,
2257#[cfg_attr(not(doctest), doc = " [(meter/second^2)^2]")]
2258pub acceleration_error_variance: ::half::f16,
2264}
2265 impl ::emcyphal_encoding::DataType for LinearVarTs {
2266 const EXTENT_BYTES: Option<u32> = None;
2268 }
2269 impl ::emcyphal_encoding::Message for LinearVarTs {}
2270 impl ::emcyphal_encoding::BufferType for LinearVarTs {
2271 type Buffer = ::emcyphal_encoding::StaticBuffer<25>;
2272 }
2273 impl LinearVarTs {}
2274 impl ::emcyphal_encoding::Serialize for LinearVarTs {
2275 fn size_bits(&self) -> usize {
2276 200
2277 }
2278 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2279 cursor.write_composite(&self.value);
2280 cursor.write_f16(self.position_error_variance);
2281 cursor.write_f16(self.velocity_error_variance);
2282 cursor.write_f16(self.acceleration_error_variance);
2283 }
2284 }
2285 impl ::emcyphal_encoding::Deserialize for LinearVarTs {
2286 fn deserialize(
2287 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2288 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2289 where
2290 Self: Sized,
2291 {
2292 Ok(LinearVarTs {
2293 value: { cursor.read_composite()? },
2294 position_error_variance: { cursor.read_f16() },
2295 velocity_error_variance: { cursor.read_f16() },
2296 acceleration_error_variance: { cursor.read_f16() },
2297 })
2298 }
2299 }
2300 }
2301 pub mod velocity1_var_ts_0_1 {
2302 #[cfg_attr(
2307 not(doctest),
2308 doc = " Linear velocity with timestamp and covariance.\n Observe that this is a structural subtype of uavcan.si.sample.velocity.Scalar.1.0.\n For a non-timestamped estimate without covariance use the raw SI type directly."
2309 )]
2310 pub struct Velocity1VarTs {
2311 pub value: crate::uavcan::si::sample::velocity::scalar_1_0::Scalar,
2317 #[cfg_attr(not(doctest), doc = " [(meter/second)^2]")]
2318 pub error_variance: ::half::f16,
2324 }
2325 impl ::emcyphal_encoding::DataType for Velocity1VarTs {
2326 const EXTENT_BYTES: Option<u32> = None;
2328 }
2329 impl ::emcyphal_encoding::Message for Velocity1VarTs {}
2330 impl ::emcyphal_encoding::BufferType for Velocity1VarTs {
2331 type Buffer = ::emcyphal_encoding::StaticBuffer<13>;
2332 }
2333 impl Velocity1VarTs {}
2334 impl ::emcyphal_encoding::Serialize for Velocity1VarTs {
2335 fn size_bits(&self) -> usize {
2336 104
2337 }
2338 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2339 cursor.write_composite(&self.value);
2340 cursor.write_f16(self.error_variance);
2341 }
2342 }
2343 impl ::emcyphal_encoding::Deserialize for Velocity1VarTs {
2344 fn deserialize(
2345 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2346 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2347 where
2348 Self: Sized,
2349 {
2350 Ok(Velocity1VarTs {
2351 value: { cursor.read_composite()? },
2352 error_variance: { cursor.read_f16() },
2353 })
2354 }
2355 }
2356 }
2357 #[allow(deprecated)]
2358 #[cfg_attr(not(test), deprecated)]
2359 pub mod velocity3_var_0_1 {
2360 #[cfg_attr(
2365 not(doctest),
2366 doc = " Linear velocity with covariance.\n Observe that this is a structural subtype of uavcan.si.unit.velocity.Scalar.1.0."
2367 )]
2368 #[deprecated]
2369 pub struct Velocity3Var {
2370 pub value: crate::uavcan::si::sample::velocity::vector3_1_0::Vector3,
2376 #[cfg_attr(
2377 not(doctest),
2378 doc = " [(meter/second)^2] Upper-right triangle of the covariance matrix."
2379 )]
2380 pub covariance_urt: [::half::f16; 6],
2386 }
2387 impl ::emcyphal_encoding::DataType for Velocity3Var {
2388 const EXTENT_BYTES: Option<u32> = None;
2390 }
2391 impl ::emcyphal_encoding::Message for Velocity3Var {}
2392 impl ::emcyphal_encoding::BufferType for Velocity3Var {
2393 type Buffer = ::emcyphal_encoding::StaticBuffer<31>;
2394 }
2395 impl Velocity3Var {}
2396 impl ::emcyphal_encoding::Serialize for Velocity3Var {
2397 fn size_bits(&self) -> usize {
2398 248
2399 }
2400 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2401 cursor.write_composite(&self.value);
2402 for value in (self.covariance_urt).iter() {
2403 cursor.write_f16(*value);
2404 }
2405 }
2406 }
2407 impl ::emcyphal_encoding::Deserialize for Velocity3Var {
2408 fn deserialize(
2409 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2410 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2411 where
2412 Self: Sized,
2413 {
2414 Ok(Velocity3Var {
2415 value: { cursor.read_composite()? },
2416 covariance_urt: {
2417 [
2418 cursor.read_f16(),
2419 cursor.read_f16(),
2420 cursor.read_f16(),
2421 cursor.read_f16(),
2422 cursor.read_f16(),
2423 cursor.read_f16(),
2424 ]
2425 },
2426 })
2427 }
2428 }
2429 }
2430 pub mod velocity3_var_0_2 {
2431 #[cfg_attr(
2436 not(doctest),
2437 doc = " Linear velocity with covariance.\n Observe that this is a structural subtype of uavcan.si.unit.velocity.Scalar.1.0."
2438 )]
2439 #[derive(
2440 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
2441 )]
2442 #[repr(C, packed)]
2443 pub struct Velocity3Var {
2444 pub value: crate::uavcan::si::unit::velocity::vector3_1_0::Vector3,
2450 #[cfg_attr(
2451 not(doctest),
2452 doc = " [(meter/second)^2] Upper-right triangle of the covariance matrix."
2453 )]
2454 pub covariance_urt: [::half::f16; 6],
2460 }
2461 impl ::emcyphal_encoding::DataType for Velocity3Var {
2462 const EXTENT_BYTES: Option<u32> = None;
2464 }
2465 impl ::emcyphal_encoding::Message for Velocity3Var {}
2466 impl ::emcyphal_encoding::BufferType for Velocity3Var {
2467 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
2468 }
2469 impl Velocity3Var {}
2470 impl ::emcyphal_encoding::Serialize for Velocity3Var {
2471 fn size_bits(&self) -> usize {
2472 192
2473 }
2474 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2475 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2476 }
2477 }
2478 impl ::emcyphal_encoding::Deserialize for Velocity3Var {
2479 fn deserialize(
2480 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2481 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2482 where
2483 Self: Sized,
2484 {
2485 Ok(Self::deserialize_zero_copy(cursor))
2486 }
2487 }
2488 #[test]
2489 fn test_layout() {
2490 assert_eq!(::core::mem::size_of::<Velocity3Var>() * 8, 192);
2491 assert_eq!(::core::mem::offset_of!(Velocity3Var, value) * 8, 0);
2492 assert_eq!(
2493 ::core::mem::offset_of!(Velocity3Var, covariance_urt) * 8,
2494 96
2495 );
2496 }
2497 }
2498 }
2499 }
2500 pub mod optics {
2501 pub mod high_color_0_1 {
2502 #[cfg_attr(
2507 not(doctest),
2508 doc = " Color in the standard 16-bit 5-6-5 RGB format (green is wider due to non-uniform color sensitivity of the human eye).\n https://en.wikipedia.org/wiki/High_color\n\n For reasons of unification, a monochrome light can be modeled using the same type,\n where the brightness is defined as the mean of the color components normalized to one:\n\n brightness = (red/MAX_RED + green/MAX_GREEN + blue/MAX_BLUE) / 3"
2509 )]
2510 pub struct HighColor {
2511 pub red: u8,
2517 pub green: u8,
2523 pub blue: u8,
2529 }
2530 impl ::emcyphal_encoding::DataType for HighColor {
2531 const EXTENT_BYTES: Option<u32> = None;
2533 }
2534 impl ::emcyphal_encoding::Message for HighColor {}
2535 impl ::emcyphal_encoding::BufferType for HighColor {
2536 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
2537 }
2538 impl HighColor {
2539 pub const MAX_RED: u8 = 31;
2540 pub const MAX_GREEN: u8 = 63;
2541 pub const MAX_BLUE: u8 = 31;
2542 }
2543 impl ::emcyphal_encoding::Serialize for HighColor {
2544 fn size_bits(&self) -> usize {
2545 16
2546 }
2547 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2548 cursor.write_u5(self.red);
2549 cursor.write_u6(self.green);
2550 cursor.write_u5(self.blue);
2551 }
2552 }
2553 impl ::emcyphal_encoding::Deserialize for HighColor {
2554 fn deserialize(
2555 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2556 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2557 where
2558 Self: Sized,
2559 {
2560 Ok(HighColor {
2561 red: { cursor.read_u5() as _ },
2562 green: { cursor.read_u6() as _ },
2563 blue: { cursor.read_u5() as _ },
2564 })
2565 }
2566 }
2567 }
2568 }
2569 pub mod thermodynamics {
2570 pub mod pressure_temp_var_ts_0_1 {
2571 #[cfg_attr(
2576 not(doctest),
2577 doc = " Timestamped fluid pressure and temperature (sampled synchronously) with covariance.\n Observe that this is a structural subtype of uavcan.si.sample.pressure.Scalar.1.0."
2578 )]
2579 pub struct PressureTempVarTs {
2580 pub timestamp:
2586 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
2587 pub pressure: crate::uavcan::si::unit::pressure::scalar_1_0::Scalar,
2593 pub temperature: crate::uavcan::si::unit::temperature::scalar_1_0::Scalar,
2599 #[cfg_attr(
2600 not(doctest),
2601 doc = " The upper-right triangle of the covariance matrix (following the matrix packing rules defined in Specification).\n 0 -- pascal^2\n 1 -- pascal*kelvin\n 2 -- kelvin^2"
2602 )]
2603 pub covariance_urt: [::half::f16; 3],
2609 }
2610 impl ::emcyphal_encoding::DataType for PressureTempVarTs {
2611 const EXTENT_BYTES: Option<u32> = None;
2613 }
2614 impl ::emcyphal_encoding::Message for PressureTempVarTs {}
2615 impl ::emcyphal_encoding::BufferType for PressureTempVarTs {
2616 type Buffer = ::emcyphal_encoding::StaticBuffer<21>;
2617 }
2618 impl PressureTempVarTs {}
2619 impl ::emcyphal_encoding::Serialize for PressureTempVarTs {
2620 fn size_bits(&self) -> usize {
2621 168
2622 }
2623 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2624 cursor.write_composite(&self.timestamp);
2625 cursor.write_composite(&self.pressure);
2626 cursor.write_composite(&self.temperature);
2627 for value in (self.covariance_urt).iter() {
2628 cursor.write_f16(*value);
2629 }
2630 }
2631 }
2632 impl ::emcyphal_encoding::Deserialize for PressureTempVarTs {
2633 fn deserialize(
2634 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2635 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2636 where
2637 Self: Sized,
2638 {
2639 Ok(PressureTempVarTs {
2640 timestamp: { cursor.read_composite()? },
2641 pressure: { cursor.read_composite()? },
2642 temperature: { cursor.read_composite()? },
2643 covariance_urt: {
2644 [cursor.read_f16(), cursor.read_f16(), cursor.read_f16()]
2645 },
2646 })
2647 }
2648 }
2649 }
2650 }
2651 pub mod time {
2652 pub mod tai64_0_1 {
2653 #[cfg_attr(
2658 not(doctest),
2659 doc = " Standard TAI64N time label (https://cr.yp.to/libtai/tai64.html). Quote from the source:\n\n TAI stands for Temps Atomique International, the current international real-time standard.\n One TAI second is defined as the duration of 9192631770 periods of the radiation corresponding\n to the transition between the two hyperfine levels of the ground state of the cesium atom.\n TAI also specifies a frame of reference. Further discussion of special relativity is outside\n the scope of this document.\n\n A TAI64 label is an integer between 0 and 2^64 referring to a particular second of real time. Integer s refers to:\n\n - the TAI second beginning exactly 2^62 - s seconds before the beginning of 1970 TAI,\n if s is between 0 inclusive and 2^62 exclusive; or\n\n - the TAI second beginning exactly s - 2^62 seconds after the beginning of 1970 TAI,\n if s is between 2^62 inclusive and 2^63 exclusive.\n"
2660 )]
2661 #[derive(
2662 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
2663 )]
2664 #[repr(C, packed)]
2665 pub struct TAI64 {
2666 #[cfg_attr(
2667 not(doctest),
2668 doc = " [nanosecond] Nanoseconds elapsed since 1970-01-01T00:00:00Z TAI."
2669 )]
2670 pub tai64n: i64,
2676 }
2677 impl ::emcyphal_encoding::DataType for TAI64 {
2678 const EXTENT_BYTES: Option<u32> = None;
2680 }
2681 impl ::emcyphal_encoding::Message for TAI64 {}
2682 impl ::emcyphal_encoding::BufferType for TAI64 {
2683 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
2684 }
2685 impl TAI64 {}
2686 impl ::emcyphal_encoding::Serialize for TAI64 {
2687 fn size_bits(&self) -> usize {
2688 64
2689 }
2690 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2691 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2692 }
2693 }
2694 impl ::emcyphal_encoding::Deserialize for TAI64 {
2695 fn deserialize(
2696 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2697 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2698 where
2699 Self: Sized,
2700 {
2701 Ok(Self::deserialize_zero_copy(cursor))
2702 }
2703 }
2704 #[test]
2705 fn test_layout() {
2706 assert_eq!(::core::mem::size_of::<TAI64>() * 8, 64);
2707 assert_eq!(::core::mem::offset_of!(TAI64, tai64n) * 8, 0);
2708 }
2709 }
2710 pub mod tai64_var_0_1 {
2711 #[derive(
2716 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
2717 )]
2718 #[repr(C, packed)]
2719 pub struct TAI64Var {
2720 pub value: crate::reg::udral::physics::time::tai64_0_1::TAI64,
2726 #[cfg_attr(
2727 not(doctest),
2728 doc = " [second^2]\n Error variance, in second squared, of the time estimate.\n Infinity indicates that the time estimates are not yet available.\n A non-positive value indicates that the error variance is unknown."
2729 )]
2730 pub error_variance: f32,
2736 }
2737 impl ::emcyphal_encoding::DataType for TAI64Var {
2738 const EXTENT_BYTES: Option<u32> = None;
2740 }
2741 impl ::emcyphal_encoding::Message for TAI64Var {}
2742 impl ::emcyphal_encoding::BufferType for TAI64Var {
2743 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
2744 }
2745 impl TAI64Var {}
2746 impl ::emcyphal_encoding::Serialize for TAI64Var {
2747 fn size_bits(&self) -> usize {
2748 96
2749 }
2750 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2751 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2752 }
2753 }
2754 impl ::emcyphal_encoding::Deserialize for TAI64Var {
2755 fn deserialize(
2756 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2757 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2758 where
2759 Self: Sized,
2760 {
2761 Ok(Self::deserialize_zero_copy(cursor))
2762 }
2763 }
2764 #[test]
2765 fn test_layout() {
2766 assert_eq!(::core::mem::size_of::<TAI64Var>() * 8, 96);
2767 assert_eq!(::core::mem::offset_of!(TAI64Var, value) * 8, 0);
2768 assert_eq!(::core::mem::offset_of!(TAI64Var, error_variance) * 8, 64);
2769 }
2770 }
2771 pub mod tai64_var_ts_0_1 {
2772 pub struct TAI64VarTs {
2777 pub timestamp:
2783 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
2784 pub value: crate::reg::udral::physics::time::tai64_var_0_1::TAI64Var,
2790 }
2791 impl ::emcyphal_encoding::DataType for TAI64VarTs {
2792 const EXTENT_BYTES: Option<u32> = None;
2794 }
2795 impl ::emcyphal_encoding::Message for TAI64VarTs {}
2796 impl ::emcyphal_encoding::BufferType for TAI64VarTs {
2797 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
2798 }
2799 impl TAI64VarTs {}
2800 impl ::emcyphal_encoding::Serialize for TAI64VarTs {
2801 fn size_bits(&self) -> usize {
2802 152
2803 }
2804 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2805 cursor.write_composite(&self.timestamp);
2806 cursor.write_composite(&self.value);
2807 }
2808 }
2809 impl ::emcyphal_encoding::Deserialize for TAI64VarTs {
2810 fn deserialize(
2811 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2812 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2813 where
2814 Self: Sized,
2815 {
2816 Ok(TAI64VarTs {
2817 timestamp: { cursor.read_composite()? },
2818 value: { cursor.read_composite()? },
2819 })
2820 }
2821 }
2822 }
2823 }
2824 }
2825 pub mod service {
2826 pub mod actuator {
2827 pub mod common {
2828 pub mod _0_1 {
2829 #[cfg_attr(
2834 not(doctest),
2835 doc = " An actuator is a device that actuates a mechanical load using electric energy from the high-voltage DC power bus.\n There are multiple kinds of actuators with a dedicated namespace for each; additionally, this \"common\" namespace\n hosts certain elements shared between several (or all) kinds."
2836 )]
2837 #[derive(
2838 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
2839 )]
2840 #[repr(C, packed)]
2841 pub struct _0 {}
2842 impl ::emcyphal_encoding::DataType for _0 {
2843 const EXTENT_BYTES: Option<u32> = Some(0);
2845 }
2846 impl ::emcyphal_encoding::Message for _0 {}
2847 impl ::emcyphal_encoding::BufferType for _0 {
2848 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
2849 }
2850 impl _0 {
2851 #[cfg_attr(
2852 not(doctest),
2853 doc = " [seconds]\n The actuator is allowed to enter a safe state (e.g., stop the controlled mechanism, disconnect itself from\n the load, etc. depending on the specifics of the application at hand) if no setpoint or readiness control messages\n have been received in this amount of time. Implementations are allowed to reduce this value, but never increase it."
2854 )]
2855 pub const CONTROL_TIMEOUT: f32 = 1_f32;
2856 #[cfg_attr(
2857 not(doctest),
2858 doc = " [second]\n This is the maximum publication period (minimum frequency) for all subjects described in this service.\n Subjects that are clocked by the setpoint should continue being published at least at this rate when setpoint is not\n being updated, unless the actuator is in the SLEEP state.\n The publication periods should be consistent across the group."
2859 )]
2860 pub const MAX_PUBLICATION_PERIOD: u8 = 1;
2861 }
2862 impl ::emcyphal_encoding::Serialize for _0 {
2863 fn size_bits(&self) -> usize {
2864 0
2865 }
2866 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
2867 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
2868 }
2869 }
2870 impl ::emcyphal_encoding::Deserialize for _0 {
2871 fn deserialize(
2872 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
2873 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
2874 where
2875 Self: Sized,
2876 {
2877 Ok(Self::deserialize_zero_copy(cursor))
2878 }
2879 }
2880 #[test]
2881 fn test_layout() {
2882 assert_eq!(::core::mem::size_of::<_0>() * 8, 0);
2883 }
2884 }
2885 pub mod fault_flags_0_1 {
2886 #[cfg_attr(
2891 not(doctest),
2892 doc = " A collection of detailed fault flags indicating problems detected by the service provider.\n A fault flag is set when the corresponding parameter exceeds its safe operating area (SOA) as defined by the vendor;\n see https://en.wikipedia.org/wiki/Safe_operating_area.\n As long as at least one flag is set, the service health should not be NOMINAL."
2893 )]
2894 pub struct FaultFlags {
2895 #[cfg_attr(
2896 not(doctest),
2897 doc = " The load is above SOA or regeneration below the SOA."
2898 )]
2899 pub overload: bool,
2905 #[cfg_attr(
2906 not(doctest),
2907 doc = " Supply voltage is above or below the SOA."
2908 )]
2909 pub voltage: bool,
2915 pub motor_temperature: bool,
2921 #[cfg_attr(
2922 not(doctest),
2923 doc = " Temperature is above or below the SOA."
2924 )]
2925 pub controller_temperature: bool,
2931 #[cfg_attr(
2932 not(doctest),
2933 doc = " The absolute velocity of the load is above the SOA."
2934 )]
2935 pub velocity: bool,
2941 #[cfg_attr(
2942 not(doctest),
2943 doc = " The load cannot be driven due to a mechanical failure."
2944 )]
2945 pub mechanical: bool,
2951 #[cfg_attr(
2952 not(doctest),
2953 doc = " The mechanical vibration level exceeds the SOA."
2954 )]
2955 pub vibration: bool,
2961 #[cfg_attr(
2962 not(doctest),
2963 doc = " Configuration is missing or invalid."
2964 )]
2965 pub configuration: bool,
2971 #[cfg_attr(
2972 not(doctest),
2973 doc = " The requested control mode is not supported by the actuator."
2974 )]
2975 pub control_mode: bool,
2981 #[cfg_attr(
2983 not(doctest),
2984 doc = " None of the above (vendor-specific)."
2985 )]
2986 pub other: bool,
2992 }
2993 impl ::emcyphal_encoding::DataType for FaultFlags {
2994 const EXTENT_BYTES: Option<u32> = None;
2996 }
2997 impl ::emcyphal_encoding::Message for FaultFlags {}
2998 impl ::emcyphal_encoding::BufferType for FaultFlags {
2999 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
3000 }
3001 impl FaultFlags {}
3002 impl ::emcyphal_encoding::Serialize for FaultFlags {
3003 fn size_bits(&self) -> usize {
3004 16
3005 }
3006 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3007 cursor.write_bool(self.overload);
3008 cursor.write_bool(self.voltage);
3009 cursor.write_bool(self.motor_temperature);
3010 cursor.write_bool(self.controller_temperature);
3011 cursor.write_bool(self.velocity);
3012 cursor.write_bool(self.mechanical);
3013 cursor.write_bool(self.vibration);
3014 cursor.write_bool(self.configuration);
3015 cursor.write_bool(self.control_mode);
3016 cursor.skip_6();
3017 cursor.write_bool(self.other);
3018 }
3019 }
3020 impl ::emcyphal_encoding::Deserialize for FaultFlags {
3021 fn deserialize(
3022 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3023 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3024 where
3025 Self: Sized,
3026 {
3027 Ok(FaultFlags {
3028 overload: { cursor.read_bool() },
3029 voltage: { cursor.read_bool() },
3030 motor_temperature: { cursor.read_bool() },
3031 controller_temperature: { cursor.read_bool() },
3032 velocity: { cursor.read_bool() },
3033 mechanical: { cursor.read_bool() },
3034 vibration: { cursor.read_bool() },
3035 configuration: { cursor.read_bool() },
3036 control_mode: { cursor.read_bool() },
3037 other: {
3038 cursor.skip_6();
3039 cursor.read_bool()
3040 },
3041 })
3042 }
3043 }
3044 }
3045 pub mod feedback_0_1 {
3046 #[cfg_attr(
3051 not(doctest),
3052 doc = " This high-rate feedback should be published once immediately after a setpoint is applied.\n It follows that the publication rate of these messages equals that of the setpoint messages.\n When setpoint messages are not being emitted, the publication rate is implementation-defined, but it should not\n be lower than the defined limit.\n The priority of this message should be the same as that of the corresponding setpoint message."
3053 )]
3054 pub struct Feedback {
3055 #[cfg_attr(
3056 not(doctest),
3057 doc = " If ENGAGED, the actuator provides service according to its nominal performance characteristics.\n Otherwise, no availability guarantees are provided.\n Notice that the feedback type is a structural subtype of the heartbeat type, so one can subscribe to a\n feedback subject using the heartbeat type. Similarly, the heartbeat type is a structural subtype of the\n Readiness type, meaning that one can use the Readiness type as well."
3058 )]
3059 pub heartbeat:
3065 crate::reg::udral::service::common::heartbeat_0_1::Heartbeat,
3066 #[cfg_attr(
3067 not(doctest),
3068 doc = " [percent]\n Percentage of the maximum rated output intensity. May exceed +-100% in case of overload.\n Positive value indicates that power is applied to the load; negative indicates that power is being sunk from the\n load into the actuator power source.\n The consumer of this message may leverage this information to manage the control loop saturation."
3069 )]
3070 pub demand_factor_pct: i8,
3076 }
3077 impl ::emcyphal_encoding::DataType for Feedback {
3078 const EXTENT_BYTES: Option<u32> = Some(63);
3080 }
3081 impl ::emcyphal_encoding::Message for Feedback {}
3082 impl ::emcyphal_encoding::BufferType for Feedback {
3083 type Buffer = ::emcyphal_encoding::StaticBuffer<3>;
3084 }
3085 impl Feedback {}
3086 impl ::emcyphal_encoding::Serialize for Feedback {
3087 fn size_bits(&self) -> usize {
3088 24
3089 }
3090 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3091 cursor.write_composite(&self.heartbeat);
3092 cursor.write_aligned_u8(self.demand_factor_pct as u8);
3093 }
3094 }
3095 impl ::emcyphal_encoding::Deserialize for Feedback {
3096 fn deserialize(
3097 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3098 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3099 where
3100 Self: Sized,
3101 {
3102 Ok(Feedback {
3103 heartbeat: { cursor.read_composite()? },
3104 demand_factor_pct: { cursor.read_u8() as _ },
3105 })
3106 }
3107 }
3108 }
3109 pub mod sp {
3110 pub mod _0_1 {
3111 #[cfg_attr(
3116 not(doctest),
3117 doc = " This is a collection of weakly-typed primitives used to control groups of actuators synchronously.\n\n Actuators are expected to subscribe using the largest array type. Publishers would choose the array type\n depending on the number of actuators in the group. The actuators would be expecting the largest array type,\n where the missing elements will be zero-filled automatically by the protocol stack thanks to the\n Implicit Zero Extension Rule (refer to the Cyphal Specification for details).\n\n The physical meaning of the values contained in the array is defined by the respective actuator service specification.\n If ratiometric control is used, then the range should be [-1, +1].\n\n It follows that a standalone actuator (that is not a member of any group) is just a special case of a group of 1,\n where the setpoint type is a single scalar.\n\n The Cyphal Specification might benefit from supporting flexible array fields to avoid having to deal with redundant\n similar types: https://en.wikipedia.org/wiki/Flexible_array_member, so that instead of having multiple types that\n differ only in size of the array fields, one could just say `float16[0] value` such that the size of zero indicates\n that the array is a flex array."
3118 )]
3119 #[derive(
3120 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3121 )]
3122 #[repr(C, packed)]
3123 pub struct _0 {}
3124 impl ::emcyphal_encoding::DataType for _0 {
3125 const EXTENT_BYTES: Option<u32> = Some(0);
3127 }
3128 impl ::emcyphal_encoding::Message for _0 {}
3129 impl ::emcyphal_encoding::BufferType for _0 {
3130 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
3131 }
3132 impl _0 {
3133 #[cfg_attr(
3134 not(doctest),
3135 doc = " The float epsilon defined for convenience.\n See https://en.wikipedia.org/wiki/Machine_epsilon."
3136 )]
3137 pub const EPSILON: ::half::f16 = ::half::f16::from_bits(4096);
3138 }
3139 impl ::emcyphal_encoding::Serialize for _0 {
3140 fn size_bits(&self) -> usize {
3141 0
3142 }
3143 fn serialize(
3144 &self,
3145 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3146 ) {
3147 cursor
3148 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3149 }
3150 }
3151 impl ::emcyphal_encoding::Deserialize for _0 {
3152 fn deserialize(
3153 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3154 ) -> ::core::result::Result<
3155 Self,
3156 ::emcyphal_encoding::DeserializeError,
3157 >
3158 where
3159 Self: Sized,
3160 {
3161 Ok(Self::deserialize_zero_copy(cursor))
3162 }
3163 }
3164 #[test]
3165 fn test_layout() {
3166 assert_eq!(::core::mem::size_of::<_0>() * 8, 0);
3167 }
3168 }
3169 pub mod scalar_0_1 {
3170 #[derive(
3175 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3176 )]
3177 #[repr(C, packed)]
3178 pub struct Scalar {
3179 pub value: ::half::f16,
3185 }
3186 impl ::emcyphal_encoding::DataType for Scalar {
3187 const EXTENT_BYTES: Option<u32> = Some(512);
3189 }
3190 impl ::emcyphal_encoding::Message for Scalar {}
3191 impl ::emcyphal_encoding::BufferType for Scalar {
3192 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
3193 }
3194 impl Scalar {}
3195 impl ::emcyphal_encoding::Serialize for Scalar {
3196 fn size_bits(&self) -> usize {
3197 16
3198 }
3199 fn serialize(
3200 &self,
3201 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3202 ) {
3203 cursor
3204 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3205 }
3206 }
3207 impl ::emcyphal_encoding::Deserialize for Scalar {
3208 fn deserialize(
3209 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3210 ) -> ::core::result::Result<
3211 Self,
3212 ::emcyphal_encoding::DeserializeError,
3213 >
3214 where
3215 Self: Sized,
3216 {
3217 Ok(Self::deserialize_zero_copy(cursor))
3218 }
3219 }
3220 #[test]
3221 fn test_layout() {
3222 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 16);
3223 assert_eq!(::core::mem::offset_of!(Scalar, value) * 8, 0);
3224 }
3225 }
3226 pub mod vector2_0_1 {
3227 #[derive(
3232 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3233 )]
3234 #[repr(C, packed)]
3235 pub struct Vector2 {
3236 pub value: [::half::f16; 2],
3242 }
3243 impl ::emcyphal_encoding::DataType for Vector2 {
3244 const EXTENT_BYTES: Option<u32> = Some(512);
3246 }
3247 impl ::emcyphal_encoding::Message for Vector2 {}
3248 impl ::emcyphal_encoding::BufferType for Vector2 {
3249 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
3250 }
3251 impl Vector2 {}
3252 impl ::emcyphal_encoding::Serialize for Vector2 {
3253 fn size_bits(&self) -> usize {
3254 32
3255 }
3256 fn serialize(
3257 &self,
3258 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3259 ) {
3260 cursor
3261 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3262 }
3263 }
3264 impl ::emcyphal_encoding::Deserialize for Vector2 {
3265 fn deserialize(
3266 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3267 ) -> ::core::result::Result<
3268 Self,
3269 ::emcyphal_encoding::DeserializeError,
3270 >
3271 where
3272 Self: Sized,
3273 {
3274 Ok(Self::deserialize_zero_copy(cursor))
3275 }
3276 }
3277 #[test]
3278 fn test_layout() {
3279 assert_eq!(::core::mem::size_of::<Vector2>() * 8, 32);
3280 assert_eq!(::core::mem::offset_of!(Vector2, value) * 8, 0);
3281 }
3282 }
3283 pub mod vector31_0_1 {
3284 #[derive(
3289 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3290 )]
3291 #[repr(C, packed)]
3292 pub struct Vector31 {
3293 pub value: [::half::f16; 31],
3299 }
3300 impl ::emcyphal_encoding::DataType for Vector31 {
3301 const EXTENT_BYTES: Option<u32> = Some(512);
3303 }
3304 impl ::emcyphal_encoding::Message for Vector31 {}
3305 impl ::emcyphal_encoding::BufferType for Vector31 {
3306 type Buffer = ::emcyphal_encoding::StaticBuffer<62>;
3307 }
3308 impl Vector31 {}
3309 impl ::emcyphal_encoding::Serialize for Vector31 {
3310 fn size_bits(&self) -> usize {
3311 496
3312 }
3313 fn serialize(
3314 &self,
3315 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3316 ) {
3317 cursor
3318 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3319 }
3320 }
3321 impl ::emcyphal_encoding::Deserialize for Vector31 {
3322 fn deserialize(
3323 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3324 ) -> ::core::result::Result<
3325 Self,
3326 ::emcyphal_encoding::DeserializeError,
3327 >
3328 where
3329 Self: Sized,
3330 {
3331 Ok(Self::deserialize_zero_copy(cursor))
3332 }
3333 }
3334 #[test]
3335 fn test_layout() {
3336 assert_eq!(::core::mem::size_of::<Vector31>() * 8, 496);
3337 assert_eq!(::core::mem::offset_of!(Vector31, value) * 8, 0);
3338 }
3339 }
3340 pub mod vector3_0_1 {
3341 #[derive(
3346 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3347 )]
3348 #[repr(C, packed)]
3349 pub struct Vector3 {
3350 pub value: [::half::f16; 3],
3356 }
3357 impl ::emcyphal_encoding::DataType for Vector3 {
3358 const EXTENT_BYTES: Option<u32> = Some(512);
3360 }
3361 impl ::emcyphal_encoding::Message for Vector3 {}
3362 impl ::emcyphal_encoding::BufferType for Vector3 {
3363 type Buffer = ::emcyphal_encoding::StaticBuffer<6>;
3364 }
3365 impl Vector3 {}
3366 impl ::emcyphal_encoding::Serialize for Vector3 {
3367 fn size_bits(&self) -> usize {
3368 48
3369 }
3370 fn serialize(
3371 &self,
3372 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3373 ) {
3374 cursor
3375 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3376 }
3377 }
3378 impl ::emcyphal_encoding::Deserialize for Vector3 {
3379 fn deserialize(
3380 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3381 ) -> ::core::result::Result<
3382 Self,
3383 ::emcyphal_encoding::DeserializeError,
3384 >
3385 where
3386 Self: Sized,
3387 {
3388 Ok(Self::deserialize_zero_copy(cursor))
3389 }
3390 }
3391 #[test]
3392 fn test_layout() {
3393 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 48);
3394 assert_eq!(::core::mem::offset_of!(Vector3, value) * 8, 0);
3395 }
3396 }
3397 pub mod vector4_0_1 {
3398 #[derive(
3403 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3404 )]
3405 #[repr(C, packed)]
3406 pub struct Vector4 {
3407 pub value: [::half::f16; 4],
3413 }
3414 impl ::emcyphal_encoding::DataType for Vector4 {
3415 const EXTENT_BYTES: Option<u32> = Some(512);
3417 }
3418 impl ::emcyphal_encoding::Message for Vector4 {}
3419 impl ::emcyphal_encoding::BufferType for Vector4 {
3420 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
3421 }
3422 impl Vector4 {}
3423 impl ::emcyphal_encoding::Serialize for Vector4 {
3424 fn size_bits(&self) -> usize {
3425 64
3426 }
3427 fn serialize(
3428 &self,
3429 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3430 ) {
3431 cursor
3432 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3433 }
3434 }
3435 impl ::emcyphal_encoding::Deserialize for Vector4 {
3436 fn deserialize(
3437 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3438 ) -> ::core::result::Result<
3439 Self,
3440 ::emcyphal_encoding::DeserializeError,
3441 >
3442 where
3443 Self: Sized,
3444 {
3445 Ok(Self::deserialize_zero_copy(cursor))
3446 }
3447 }
3448 #[test]
3449 fn test_layout() {
3450 assert_eq!(::core::mem::size_of::<Vector4>() * 8, 64);
3451 assert_eq!(::core::mem::offset_of!(Vector4, value) * 8, 0);
3452 }
3453 }
3454 pub mod vector6_0_1 {
3455 #[derive(
3460 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3461 )]
3462 #[repr(C, packed)]
3463 pub struct Vector6 {
3464 pub value: [::half::f16; 6],
3470 }
3471 impl ::emcyphal_encoding::DataType for Vector6 {
3472 const EXTENT_BYTES: Option<u32> = Some(512);
3474 }
3475 impl ::emcyphal_encoding::Message for Vector6 {}
3476 impl ::emcyphal_encoding::BufferType for Vector6 {
3477 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
3478 }
3479 impl Vector6 {}
3480 impl ::emcyphal_encoding::Serialize for Vector6 {
3481 fn size_bits(&self) -> usize {
3482 96
3483 }
3484 fn serialize(
3485 &self,
3486 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3487 ) {
3488 cursor
3489 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3490 }
3491 }
3492 impl ::emcyphal_encoding::Deserialize for Vector6 {
3493 fn deserialize(
3494 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3495 ) -> ::core::result::Result<
3496 Self,
3497 ::emcyphal_encoding::DeserializeError,
3498 >
3499 where
3500 Self: Sized,
3501 {
3502 Ok(Self::deserialize_zero_copy(cursor))
3503 }
3504 }
3505 #[test]
3506 fn test_layout() {
3507 assert_eq!(::core::mem::size_of::<Vector6>() * 8, 96);
3508 assert_eq!(::core::mem::offset_of!(Vector6, value) * 8, 0);
3509 }
3510 }
3511 pub mod vector8_0_1 {
3512 #[derive(
3517 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3518 )]
3519 #[repr(C, packed)]
3520 pub struct Vector8 {
3521 pub value: [::half::f16; 8],
3527 }
3528 impl ::emcyphal_encoding::DataType for Vector8 {
3529 const EXTENT_BYTES: Option<u32> = Some(512);
3531 }
3532 impl ::emcyphal_encoding::Message for Vector8 {}
3533 impl ::emcyphal_encoding::BufferType for Vector8 {
3534 type Buffer = ::emcyphal_encoding::StaticBuffer<16>;
3535 }
3536 impl Vector8 {}
3537 impl ::emcyphal_encoding::Serialize for Vector8 {
3538 fn size_bits(&self) -> usize {
3539 128
3540 }
3541 fn serialize(
3542 &self,
3543 cursor: &mut ::emcyphal_encoding::WriteCursor<'_>,
3544 ) {
3545 cursor
3546 .write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3547 }
3548 }
3549 impl ::emcyphal_encoding::Deserialize for Vector8 {
3550 fn deserialize(
3551 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3552 ) -> ::core::result::Result<
3553 Self,
3554 ::emcyphal_encoding::DeserializeError,
3555 >
3556 where
3557 Self: Sized,
3558 {
3559 Ok(Self::deserialize_zero_copy(cursor))
3560 }
3561 }
3562 #[test]
3563 fn test_layout() {
3564 assert_eq!(::core::mem::size_of::<Vector8>() * 8, 128);
3565 assert_eq!(::core::mem::offset_of!(Vector8, value) * 8, 0);
3566 }
3567 }
3568 }
3569 pub mod status_0_1 {
3570 #[cfg_attr(
3575 not(doctest),
3576 doc = " Auxiliary actuator status information published at a low rate asynchronously, usually at 1 Hz.\n It is mostly intended for diagnostics and logging purposes.\n In this revision this type is common for all kinds of actuators, but in the future it may be replaced\n with per-kind specializations."
3577 )]
3578 pub struct Status {
3579pub motor_temperature: crate::uavcan::si::unit::temperature::scalar_1_0::Scalar,
3585#[cfg_attr(not(doctest), doc = " Sampled temperatures. If multiple values are available, reduction is implementation-defined.")]
3586pub controller_temperature: crate::uavcan::si::unit::temperature::scalar_1_0::Scalar,
3592#[cfg_attr(not(doctest), doc = " Incremented once per occurrence. Reset to zero when ENGAGED.\n The exact definition of what constitutes an error is implementation-dependent.")]
3593pub error_count: u32,
3599#[cfg_attr(not(doctest), doc = " TODO: add vibration")]
3600pub fault_flags: crate::reg::udral::service::actuator::common::fault_flags_0_1::FaultFlags,
3606}
3607 impl ::emcyphal_encoding::DataType for Status {
3608 const EXTENT_BYTES: Option<u32> = Some(63);
3610 }
3611 impl ::emcyphal_encoding::Message for Status {}
3612 impl ::emcyphal_encoding::BufferType for Status {
3613 type Buffer = ::emcyphal_encoding::StaticBuffer<14>;
3614 }
3615 impl Status {}
3616 impl ::emcyphal_encoding::Serialize for Status {
3617 fn size_bits(&self) -> usize {
3618 112
3619 }
3620 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3621 cursor.write_composite(&self.motor_temperature);
3622 cursor.write_composite(&self.controller_temperature);
3623 cursor.write_aligned_u32(self.error_count);
3624 cursor.write_composite(&self.fault_flags);
3625 }
3626 }
3627 impl ::emcyphal_encoding::Deserialize for Status {
3628 fn deserialize(
3629 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3630 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3631 where
3632 Self: Sized,
3633 {
3634 Ok(Status {
3635 motor_temperature: { cursor.read_composite()? },
3636 controller_temperature: { cursor.read_composite()? },
3637 error_count: { cursor.read_u32() as _ },
3638 fault_flags: { cursor.read_composite()? },
3639 })
3640 }
3641 }
3642 }
3643 }
3644 pub mod esc {
3645 pub mod _0_1 {
3646 #[cfg_attr(
3651 not(doctest),
3652 doc = " The electronic speed controller (ESC) service is designed for controlling and monitoring electric drives.\n From the standpoint of this standard, an electric drive is just a special case of a servo. For generality,\n COTS electric drives are recommended to also support the servo interface defined in the adjacent namespace.\n\n ESCs (drives) are segregated into groups. Each ESC in a group has an index that is unique within the group.\n Drives in a group are commanded synchronously by publishing a message containing an array of setpoints.\n There are several subjects defined:\n\n - Setpoint array subject. Every participant subscribes to the same setpoint subject.\n Every message is consumed by all participants according to their index in the group.\n The setpoint subject defines the group. There may be an arbitrary number of such groups in the network.\n\n - Readiness subject. Every participant subscribes to the same readiness control subject which is used to command\n the state of the group: sleep, standby, or engaged. In many cases there will be one global subject controlling\n the state of the entire system; in other cases there will be dedicated controls on a per-subsystem basis.\n\n - Feedback subjects published by each ESC separately, as shown on the diagram below.\n\n SUBJECT NAME SUBJECT TYPE\n +----------------+\n | Controller |---------+------------+----... setpoint reg.udral.service.actuator.common.sp.*\n | |-------+-)----------+-)----... readiness reg.udral.service.common.Readiness\n +----------------+ | | | |\n ^ ^ ^ ^ ^ ^ ^ ^ v v v v\n | | | | | | | | +---------+ +---------+\n | | | | | | | | |Drive i=0| |Drive i=1| ...\n | | | | | | | | +---------+ +---------+\n | | | | | | | | | | | | | | | |\n | | | | | | | +-----+ | | | | | | | feedback reg.udral.service.actuator.common.Feedback\n | | | | | | +---------+ | | | | | | status reg.udral.service.actuator.common.Status\n | | | | | +-------------+ | | | | | power reg.udral.physics.electricity.PowerTs\n | | | | +-----------------+ | | | | dynamics reg.udral.physics.dynamics.rotation.PlanarTs\n | | | | | | | |\n | | | +---------------------------+ | | |\n | | +-------------------------------+ | |\n | +-----------------------------------+ |\n +---------------------------------------+\n\n Notice that the physics subjects are timestamped.\n\n Vendor/application-specific subjects are not shown here.\n Vendors are encouraged to publish additional data (e.g., temperatures) on separate subjects.\n\n\n SETPOINT SUBJECT\n\n The setpoint subject is ignored unless the drive is ENGAGED. As long as the drive is not ENGAGED, it shall not apply\n any power to the load excepting non-operational scenarios such as maintenance and diagnostics, which are\n outside of the scope of this service definition. More on readiness and safety in the next section.\n\n Upon reception of a setpoint message, a group participant fetches its setpoint from the array using the array\n element whose index equals the index of the group participant. By virtue of the Implicit Zero Extension Rule,\n if the message is too short, the setpoint will be interpreted as zero.\n\n If no valid setpoint was received in CONTROL_TIMEOUT or a lower implementation-specific value,\n the drive should assume a zero setpoint for safety reasons.\n The minimum setpoint publication period should be at least twice lower than its timeout.\n\n While stopped, the drive may either allow the load to freewheel or it may force it to a particular parking position,\n depending on the implementation requirements. The actual state of the load may be continuously reported using the\n dynamics subject. Notice that per the safety rule introduced earlier, the parking position may be impossile\n to enforce unless the drive is ENGAGED because it may require delivering power to the load.\n\n The setpoint message types that can be used to command a group of drives are defined in\n reg.udral.service.actuator.common.sp; please read the documentation related to that namespace for further information.\n Servo setpoint message types may also be supported on an implementation-specific basis for enhanced interoperability.\n If the group is controlled using different setpoint subjects concurrently, the behavior is implementation-defined.\n\n The following control modes are defined, none of which are mandatory to support.\n The control mode in use is to be specified using the register API.\n This service does not support switching the control mode or setting the motion profile at runtime;\n for that, please refer to the servo service.\n\n 0. Ratiometric voltage control. Each setpoint scalar is a value normalized/saturated in [-1, +1] representing\n the Q-axis/phase/armature (depending on the type of the drive) voltage as a fraction of the maximum.\n This control mode emulates the behavior of a typical RCPWM-controlled BLDC drive.\n\n 1. Ratiometric current/torque control. Each setpoint scalar is a value normalized/saturated in [-1, +1] representing\n the Q-axis/phase/armature (depending on the type of the drive) current as a fraction of the maximum.\n A negative setpoint during forward rotation (positive during reverse rotation) commands braking.\n\n 2. Speed control. Each setpoint scalar contains the target angular velocity of the load in radian/second.\n\n -. More control modes may be added later. Which control modes are supported is implementation-defined.\n\n Considerations that apply to all control modes:\n - Negative setpoint values represent reversal; a positive setpoint is co-directed with positive rotation/torque.\n - If reverse operation is not supported, negative values should be clamped to zero.\n - A non-finite setpoint is to be treated as zero.\n\n\n READINESS SUBJECT\n\n The default state is STANDBY. While in this state, the drive is not allowed to deliver power to the load,\n and the setpoint subject is ignored. The drive shall enter this state automatically if the readiness subject\n is not updated for CONTROL_TIMEOUT.\n\n While the drive is ENGAGED, the setpoint commands are processed normally as described in the adjacent section.\n If the drive does not support bidirectional operation, implementations are recommended to ensure that the load\n is driven at some minimum power level (idling) while the drive is ENGAGED regardless of the commanded setpoint,\n unless such behavior is deemed incompatible with the functional requirements of the controlled drive.\n\n If the selected readiness state is SLEEP, the behavior is implementation-defined. Implementations are recommended to\n power off the high-voltage circuitry and all non-essential components (e.g., LED indication, sensors, etc.)\n to minimize the power consumption.\n\n Implementations are recommended to announce transitions between the readiness states using audiovisual feedback.\n\n The worst-case state transition latency is not defined. The controlling element (that is, the unit that publishes\n to the setpoint and readiness subjects) is expected to monitor the actual readiness status of each component using\n the feedback subject. For example, a sensorless electric motor drive may choose to spool-up before entering the\n ENGAGED state, which would obviously take time; as soon as the spool-up is finished, the drive would switch its\n reported status from STANDBY to ENGAGED, thereby indicating that it is ready for normal operation.\n\n\n PUBLISHED SUBJECTS\n\n The following subjects shall be published immediately after a new setpoint is applied even if the drive is STANDBY:\n\n SUBJECT RECOMMENDED PRIORITY\n ---------------------------------------------\n feedback same as the setpoint\n power second to the setpoint\n dynamics second to the setpoint\n\n If no setpoint is being published, these subjects should continue being updated at least at 1/MAX_PUBLICATION_PERIOD.\n The publication rate requirements do not apply if the readiness state is SLEEP.\n\n If the setpoint publication rate exceeds 50 Hz, implementations are allowed (but not required) to throttle these\n subjects by dropping some of the messages such that the publication rate of each subject does not exceed 50 Hz.\n Implementations operating over Classic CAN are recommended to do this.\n\n The other subjects may be published at an implementation-defined rate and priority,\n which should be consistent across the group.\n\n Implementations are encouraged to provide additional subjects for enhanced feedback and monitoring.\n\n The measurements carried by the published messages should be low-pass filtered with an adequate cutoff frequency to\n avoid aliasing effects. Implementations should strive to sample all parameters simultaneously.\n\n If a float-typed reported quantity is unknown, the corresponding value should be NaN.\n\n\n CONVENTIONS AND ASSUMPTIONS\n\n A drive powers a rotary mechanical load that may be connected via a gearbox. It is the responsibility of\n the drive to account for the gear ratio of the gearbox when calculating related parameters such as angular\n velocity or torque.\n\n It is assumed that there is a well-defined direction of rotation that is referred to as forward rotation.\n A positive angular velocity represents forward rotation. Likewise, forward torque is positive.\n\n It is assumed that the drive is powered from a DC electric power supply network. A positive electric current\n represents current flowing from the network into the drive, also referred to as the state of driving/motoring.\n The opposite -- braking/regeneration -- is represented by negative current.\n\n Excepting edge cases and transients, torque and current are generally of the same sign.\n The above is summarized on the following four-quadrant diagram:\n\n +velocity\n ^\n braking,| forward,\n negative| positive\n power | power\n -----------+----------> +torque/current\n reverse,| braking,\n positive| negative\n power | power\n"
3653 )]
3654 #[derive(
3655 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3656 )]
3657 #[repr(C, packed)]
3658 pub struct _0 {}
3659 impl ::emcyphal_encoding::DataType for _0 {
3660 const EXTENT_BYTES: Option<u32> = Some(0);
3662 }
3663 impl ::emcyphal_encoding::Message for _0 {}
3664 impl ::emcyphal_encoding::BufferType for _0 {
3665 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
3666 }
3667 impl _0 {}
3668 impl ::emcyphal_encoding::Serialize for _0 {
3669 fn size_bits(&self) -> usize {
3670 0
3671 }
3672 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3673 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3674 }
3675 }
3676 impl ::emcyphal_encoding::Deserialize for _0 {
3677 fn deserialize(
3678 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3679 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3680 where
3681 Self: Sized,
3682 {
3683 Ok(Self::deserialize_zero_copy(cursor))
3684 }
3685 }
3686 #[test]
3687 fn test_layout() {
3688 assert_eq!(::core::mem::size_of::<_0>() * 8, 0);
3689 }
3690 }
3691 }
3692 pub mod servo {
3693 pub mod _0_1 {
3694 #[cfg_attr(
3699 not(doctest),
3700 doc = " A servo can actuate either a translational or rotary load using electric power from the high-voltage DC bus.\n\n The type of load (translational or rotational) dictates which type is used for commanding the setpoint and reporting\n the status:\n - reg.udral.physics.dynamics.rotation.Planar[Ts]\n - reg.udral.physics.dynamics.translation.Linear[Ts]\n For generality, either or both of these types are referred to as \"timestamped dynamics\" or \"non-timestamped dynamics\".\n\n The default readiness state is STANDBY. While in this state, the servo is not allowed to apply force to the load,\n and the setpoint subject is ignored. The servo shall enter the STANDBY state automatically if the readiness subject\n is not updated for CONTROL_TIMEOUT.\n\n The subjects defined by this service are shown on the following canvas. Implementers are encouraged to add\n custom subjects with additional data. Notice that the physics subjects are timestamped.\n\n SUBJECT NAME SUBJECT TYPE RATE\n\n +------------+ setpoint +------------+ (non-timestamped dynamics) (see below) R\n | |--------------------->| |\n | | readiness | | reg.udral.service.common.Readiness any\n | |--------------------->| |\n | | feedback | | reg.udral.service.actuator.common.Feedback R\n | |<---------------------| |\n | Controller | status | Servo | reg.udral.service.actuator.common.Status any\n | |<---------------------| |\n | | power | | reg.udral.physics.electricity.PowerTs R\n | |<---------------------| |\n | | dynamics | | (timestamped dynamics) R\n | |<---------------------| |\n +------------+ +------------+\n\n Should it be necessary to control a group of servos in lockstep, an arbitrary number of them may subscribe\n to the same setpoint subject (their published subjects would be different of course).\n\n If the servo is ENGAGED, setpoint messages are processed as follows: the first field of the kinematic setpoint type\n that contains a finite value is taken as the commanded setpoint. The following non-negative finite fields define\n the motion profile, where negative and non-finite values are ignored.\n\n For example, a translational dynamics message containing the following values:\n position = +0.35\n velocity = NaN\n acceleration = NaN\n force = 30\n ...is interpreted as follows: position the load at 0.35 meters relative to the neutral, limit the force to 30 newton,\n do not limit the velocity and acceleration. Here is another example:\n angular position = NaN\n angular velocity = +400\n angular acceleration = NaN\n torque = 50\n which is interpreted as follows: reach the angular velocity of 400 radian/second in the forward direction,\n limit the torque to 50 newton*meters, do not limit the acceleration.\n\n The motion profile parameters that are not supported are to be silently ignored by the servo. If the commanded\n parameter cannot be controlled by the servo, the setpoint is to be ignored. For example, in the second example above,\n if the servo does not support angular velocity control, the setpoint message would be discarded.\n\n The above describes the typical use case where each servo is controlled over a dedicated setpoint\n subject independently (or a group of servos are controlled in lockstep using the same setpoint subject).\n Some applications may require synchronous independent control of multiple servos in a group, similar to ESC.\n To address this, a compliant servo should support another operating mode where the controlled quantity\n (position, velocity, force, etc.) is selected statically along with the motion profile (using the register API),\n and the servo subscribes to the setpoint subject of type \"reg.udral.service.actuator.common.sp.*\".\n Having its index in the group configured statically, the servo fetches the setpoint from the appropriate\n index in the setpoint array.\n The resulting topology closely resembles that of the ESC service:\n\n SUBJECT NAME SUBJECT TYPE\n +----------------+\n | Controller |---------+------------+----... setpoint reg.udral.service.actuator.common.sp.*\n | |-------+-)----------+-)----... readiness reg.udral.service.common.Readiness\n +----------------+ | | | |\n ^ ^ ^ ^ ^ ^ ^ ^ v v v v\n | | | | | | | | +---------+ +---------+\n | | | | | | | | |Servo i=0| |Servo i=1| ...\n | | | | | | | | +---------+ +---------+\n | | | | | | | | | | | | | | | |\n | | | | | | | +-----+ | | | | | | | feedback reg.udral.service.actuator.common.Feedback\n | | | | | | +---------+ | | | | | | status reg.udral.service.actuator.common.Status\n | | | | | +-------------+ | | | | | power reg.udral.physics.electricity.PowerTs\n | | | | +-----------------+ | | | | dynamics (timestamped dynamics)\n | | | | | | | |\n | | | +---------------------------+ | | |\n | | +-------------------------------+ | |\n | +-----------------------------------+ |\n +---------------------------------------+\n\n If the selected readiness state is SLEEP, the behavior is implementation-defined. Implementations are recommended to\n power off the high-voltage circuitry and all non-essential components (e.g., LED indication, sensors, etc.)\n to minimize the power consumption. The publication rate requirements do not apply if the state is SLEEP.\n\n The worst-case readiness state transition latency is not defined.\n\n The following subjects shall be published immediately after a new setpoint is applied even if the servo is STANDBY:\n\n SUBJECT NAME RECOMMENDED PRIORITY\n ---------------------------------------------\n feedback same as the setpoint\n power second to the setpoint\n dynamics second to the setpoint\n\n If no setpoint is being published, these subjects should continue being updated at least at 1/MAX_PUBLICATION_PERIOD.\n\n If the setpoint publication rate exceeds 50 Hz, implementations are allowed (but not required) to throttle these\n subjects by dropping some of the messages such that the publication rate of each subject does not exceed 50 Hz.\n Implementations operating over Classic CAN are recommended to do this.\n\n The other subjects may be published at an implementation-defined rate and priority,\n which should be consistent across the group.\n\n The measurements carried by the published messages should be low-pass filtered with an adequate cutoff frequency to\n avoid aliasing effects. Implementations should strive to sample all parameters simultaneously.\n\n It is assumed that the servo is powered from a DC electric power supply network. A positive electric current\n represents current flowing from the DC network into the servo (negative represents regeneration).\n\n Excepting edge cases and transients, torque/force and current are generally of the same sign (barring the difference\n introduced by the power dissipated by the servo itself).\n\n +velocity\n ^\n braking,| forward,\n negative| positive\n power | power\n -----------+----------> +torque/force/current\n reverse,| braking,\n positive| negative\n power | power\n\n An example implementation is available at https://github.com/OpenCyphal/demos"
3701 )]
3702 #[derive(
3703 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3704 )]
3705 #[repr(C, packed)]
3706 pub struct _0 {}
3707 impl ::emcyphal_encoding::DataType for _0 {
3708 const EXTENT_BYTES: Option<u32> = Some(0);
3710 }
3711 impl ::emcyphal_encoding::Message for _0 {}
3712 impl ::emcyphal_encoding::BufferType for _0 {
3713 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
3714 }
3715 impl _0 {}
3716 impl ::emcyphal_encoding::Serialize for _0 {
3717 fn size_bits(&self) -> usize {
3718 0
3719 }
3720 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3721 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3722 }
3723 }
3724 impl ::emcyphal_encoding::Deserialize for _0 {
3725 fn deserialize(
3726 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3727 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3728 where
3729 Self: Sized,
3730 {
3731 Ok(Self::deserialize_zero_copy(cursor))
3732 }
3733 }
3734 #[test]
3735 fn test_layout() {
3736 assert_eq!(::core::mem::size_of::<_0>() * 8, 0);
3737 }
3738 }
3739 }
3740 }
3741 pub mod battery {
3742 pub mod _0_1 {
3743 #[cfg_attr(
3748 not(doctest),
3749 doc = " This is the smart battery monitoring service. A smart battery is required to publish on the following subjects:\n\n SUBJECT TYPE TYP. RATE [Hz]\n energy_source reg.udral.physics.electricity.SourceTs 1...100\n status reg.udral.service.battery.Status ~1\n parameters reg.udral.service.battery.Parameters ~0.2\n\n Observe that only the first subject can be used for estimating the endurance of the power source. The other subjects\n are designed for monitoring, diagnostics, and maintenance.\n\n Optionally, the battery service can subscribe to a readiness control subject (see reg.udral.service.common.Readiness),\n which enables the following two optional capabilities:\n\n - SLEEP mode: when the readiness subject commands the sleep state, the battery management system may enter a\n low power consumption state, possibly deactivating some of its capabilities.\n\n - STANDBY mode: the battery management system may implement additional safety protections that may otherwise\n interfere with the normal operation of the vehicle. For example, the traction battery may limit the maximum\n load current and the depth of discharge unless the commanded state is ENGAGED. By doing so, the battery can\n protect itself and the supplied high-voltage DC network from accidental damage while the vehicle is parked.\n Limiting the output power or discharge of the traction battery might lead to catastrophic consequences in\n an aerial vehicle, hence such safety checks are to be disabled once the battery is commanded into the ENGAGED\n state.\n\n If readiness state selection is not supported, the battery may not subscribe to the readiness control subject,\n in which case it should permanently report its state as ENGAGED unless the battery is unfit for use (e.g., due\n to degradation or a failure).\n\n By convention, positive current flows from the DC network into the battery. Therefore, the current is\n negative when the battery powers the system, and positive when it is being charged.\n\n Systems that leverage multiple battery packs simultaneously should be configured to publish the status of each\n pack on a separate subject.\n\n Published quantities should be low-pass filtered to avoid aliasing effects.\n Publishers should strive to sample all parameters atomically.\n\n The reported quantities are focused on the amount of energy that can be reclaimed from the battery. In a\n simplified view, this can be seen as the amount of energy that is \"stored\" in the battery; however, this\n interpretation is not strictly correct because the amount of retrievable energy may be dependent on external\n factors such as the temperature of the battery or the load current. Energy estimation is hard and requires\n accurate modeling of the state of the battery, which may be impossible to do without precise tracking of each\n charging cycle. Despite the complications, this is considered to be a superior approach compared to the commonly\n used alternative where the state estimation is focused on the electric charge, because the latter cannot be used\n directly to predict the endurance of the system.\n\n The methods of energy estimation are implementation-defined."
3750 )]
3751 #[derive(
3752 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3753 )]
3754 #[repr(C, packed)]
3755 pub struct _0 {}
3756 impl ::emcyphal_encoding::DataType for _0 {
3757 const EXTENT_BYTES: Option<u32> = Some(0);
3759 }
3760 impl ::emcyphal_encoding::Message for _0 {}
3761 impl ::emcyphal_encoding::BufferType for _0 {
3762 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
3763 }
3764 impl _0 {}
3765 impl ::emcyphal_encoding::Serialize for _0 {
3766 fn size_bits(&self) -> usize {
3767 0
3768 }
3769 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3770 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3771 }
3772 }
3773 impl ::emcyphal_encoding::Deserialize for _0 {
3774 fn deserialize(
3775 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3776 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3777 where
3778 Self: Sized,
3779 {
3780 Ok(Self::deserialize_zero_copy(cursor))
3781 }
3782 }
3783 #[test]
3784 fn test_layout() {
3785 assert_eq!(::core::mem::size_of::<_0>() * 8, 0);
3786 }
3787 }
3788 pub mod error_0_1 {
3789 #[cfg_attr(
3794 not(doctest),
3795 doc = " Generic error codes reported by the service provider.\n An error is reported when the corresponding parameter exceeds its safe operating area (SOA) as defined by the vendor;\n see https://en.wikipedia.org/wiki/Safe_operating_area.\n As long as an error condition is present, the service health should not be NOMINAL.\n\n If there are multiple error conditions present, the most severe one should be reported. The severity ordering\n is implementation-defined. Barring special requirements, it is recommended to give preference to errors whose\n code is smaller (e.g., BAD_BATTERY trumps TEMPERATURE_COLD)."
3796 )]
3797 #[derive(
3798 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
3799 )]
3800 #[repr(C, packed)]
3801 pub struct Error {
3802 pub value: u8,
3808 }
3809 impl ::emcyphal_encoding::DataType for Error {
3810 const EXTENT_BYTES: Option<u32> = None;
3812 }
3813 impl ::emcyphal_encoding::Message for Error {}
3814 impl ::emcyphal_encoding::BufferType for Error {
3815 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
3816 }
3817 impl Error {
3818 #[cfg_attr(not(doctest), doc = " Normal operation.")]
3819 pub const NONE: u8 = 0;
3820 #[cfg_attr(
3821 not(doctest),
3822 doc = " The battery should not be used anymore. Detection criteria are implementation-defined."
3823 )]
3824 pub const BAD_BATTERY: u8 = 10;
3825 #[cfg_attr(
3826 not(doctest),
3827 doc = " The battery requires offline maintenance."
3828 )]
3829 pub const NEEDS_SERVICE: u8 = 11;
3830 #[cfg_attr(
3831 not(doctest),
3832 doc = " An internal error in the battery management system, not related to the battery itself."
3833 )]
3834 pub const BMS_ERROR: u8 = 20;
3835 #[cfg_attr(
3836 not(doctest),
3837 doc = " The battery/BMS/node/service configuration is missing or invalid."
3838 )]
3839 pub const CONFIGURATION: u8 = 30;
3840 #[cfg_attr(
3841 not(doctest),
3842 doc = " The battery is discharged beyond the design limits and may have incurred damage."
3843 )]
3844 pub const OVERDISCHARGE: u8 = 50;
3845 #[cfg_attr(
3846 not(doctest),
3847 doc = " The charge or discharge rate exceeds the safe operating limits."
3848 )]
3849 pub const OVERLOAD: u8 = 51;
3850 pub const CELL_OVERVOLTAGE: u8 = 60;
3851 #[cfg_attr(
3852 not(doctest),
3853 doc = " Voltage of one of the battery cells exceeds its SOA."
3854 )]
3855 pub const CELL_UNDERVOLTAGE: u8 = 61;
3856 #[cfg_attr(
3857 not(doctest),
3858 doc = " The sum of cell voltages is far from the total pack voltage.\n The threshold is implementation-defined."
3859 )]
3860 pub const CELL_COUNT: u8 = 62;
3861 pub const TEMPERATURE_HOT: u8 = 100;
3862 #[cfg_attr(
3863 not(doctest),
3864 doc = " At least one cell is above/below the temperature SOA."
3865 )]
3866 pub const TEMPERATURE_COLD: u8 = 101;
3867 }
3868 impl ::emcyphal_encoding::Serialize for Error {
3869 fn size_bits(&self) -> usize {
3870 8
3871 }
3872 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
3873 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
3874 }
3875 }
3876 impl ::emcyphal_encoding::Deserialize for Error {
3877 fn deserialize(
3878 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
3879 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
3880 where
3881 Self: Sized,
3882 {
3883 Ok(Self::deserialize_zero_copy(cursor))
3884 }
3885 }
3886 #[test]
3887 fn test_layout() {
3888 assert_eq!(::core::mem::size_of::<Error>() * 8, 8);
3889 assert_eq!(::core::mem::offset_of!(Error, value) * 8, 0);
3890 }
3891 }
3892 pub mod parameters_0_3 {
3893 #[cfg_attr(
3898 not(doctest),
3899 doc = " Smart battery parameter message. It is mostly intended for automated battery charging and maintenance systems.\n This message is modeled after the Smart Battery Data Specification (SBS) and the MAVLink battery status messages.\n\n The values carried by this message are either constant or slow-changing, so, generally, the publishing frequency\n should not be higher than 0.2 Hz, and the priority should be either OPTIONAL or SLOW.\n\n All parameters are required unless specifically stated otherwise.\n For non-rechargeable batteries all \"charge_*\" parameters should be NaN."
3900 )]
3901 pub struct Parameters {
3902 #[cfg_attr(
3903 not(doctest),
3904 doc = " A statistically unique number that can be used to identify this exact battery for logging and diagnostic purposes.\n This value should be invariant to the identity of the reporting node unless it is an integral part of the battery.\n If the battery supports SBS, the recommended way to populate this field is from two CRC-32C (Castagnoli) values as:\n - 32 most significant bits identify the vendor as: CRC32C(ManufacturerName)\n - 32 least significant bits identify the battery as: CRC32C(DeviceName + ManufactureDate + SerialNumber)\n If the battery does not support SBS, the vendor may choose arbitrary random numbers.\n Note that these are mere recommendations. The only hard requirement for this field is to be statistically unique."
3905 )]
3906 pub unique_id: u64,
3912 #[cfg_attr(
3913 not(doctest),
3914 doc = " The total mass of the battery, including the packaging, electronics, cabling, and all auxiliary items, if any.\n May be used for predicting the kinematic parameters of the vehicle.\n NaN if unknown."
3915 )]
3916 pub mass: crate::uavcan::si::unit::mass::scalar_1_0::Scalar,
3922 #[cfg_attr(
3923 not(doctest),
3924 doc = " The maximum total charge of the pack, at 100% SoH, specified by the manufacturer."
3925 )]
3926 pub design_capacity:
3932 crate::uavcan::si::unit::electric_charge::scalar_1_0::Scalar,
3933 #[cfg_attr(
3934 not(doctest),
3935 doc = " The minimum (end of discharge) and the maximum (end of charge) resting cell voltage specified by the manufacturer\n at 100% SoH. Example: {2.8, 4.2} V. These voltages correspond to resting voltages; i.e., the stabilized voltages after\n the discharge/charge has been terminated. Voltage below the min may be observed during discharge due to the cell's\n internal resistance. Voltage above the max voltage may be observed during regenerative braking/charging etc due to\n the cell's internal resistance."
3936 )]
3937 pub design_cell_voltage_min_max:
3943 [crate::uavcan::si::unit::voltage::scalar_1_0::Scalar; 2],
3944 #[cfg_attr(
3945 not(doctest),
3946 doc = " Recommended continuous discharge current of the battery."
3947 )]
3948 pub discharge_current:
3954 crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
3955 #[cfg_attr(
3956 not(doctest),
3957 doc = " Maximum current that may be safely discharged at least for 5 seconds."
3958 )]
3959 pub discharge_current_burst:
3965 crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
3966 #[cfg_attr(
3967 not(doctest),
3968 doc = " Recommended continuous charge current of the battery."
3969 )]
3970 pub charge_current:
3976 crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
3977 #[cfg_attr(
3978 not(doctest),
3979 doc = " Recommended safest highest continuous charge current for the battery.\n This may cause accelerated aging of the battery."
3980 )]
3981 pub charge_current_fast:
3987 crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
3988 #[cfg_attr(
3989 not(doctest),
3990 doc = " End-of-charging current threshold. Charging may be terminated when the current falls below this threshold."
3991 )]
3992 pub charge_termination_threshold:
3998 crate::uavcan::si::unit::electric_current::scalar_1_0::Scalar,
3999 #[cfg_attr(
4000 not(doctest),
4001 doc = " The total voltage (not per-cell) that may be used by the charger to charge the battery pack."
4002 )]
4003 pub charge_voltage: crate::uavcan::si::unit::voltage::scalar_1_0::Scalar,
4009 #[cfg_attr(
4010 not(doctest),
4011 doc = " The number of charge-discharge cycles. Zero if the battery is new. May increase at runtime.\n What constitutes a charge-discharge cycle is implementation-defined."
4012 )]
4013 pub cycle_count: u16,
4019 #[cfg_attr(
4021 not(doctest),
4022 doc = " The number of cells connected in series. This value should match the array of cell voltages reported via Status."
4023 )]
4024 pub series_cell_count: u8,
4030 #[cfg_attr(
4031 not(doctest),
4032 doc = " [percent]\n The SoH of the battery, or best guess thereof; ranges from 0 (unusable) to 100 (new)."
4033 )]
4034 pub state_of_health_pct: u8,
4040 #[cfg_attr(
4042 not(doctest),
4043 doc = " The battery technology information may be leveraged by the charger to choose the appropriate charging strategy."
4044 )]
4045 pub technology:
4051 crate::reg::udral::service::battery::technology_0_1::Technology,
4052 #[cfg_attr(
4053 not(doctest),
4054 doc = " The nominal voltage of the battery pack (not per-cell) as defined by the vendor.\n E.g., a typical 22S LiCoO2 pack would usually report 81.4 V here."
4055 )]
4056 pub nominal_voltage: crate::uavcan::si::unit::voltage::scalar_1_0::Scalar,
4062 #[cfg_attr(
4063 not(doctest),
4064 doc = " The approximate UNIX Epoch time when the battery was manufactured, zero if unknown."
4065 )]
4066 pub unix_manufacture_time: u64,
4072 #[cfg_attr(
4073 not(doctest),
4074 doc = " An arbitrary human-readable textual description of this battery. Empty if unknown/unused.\n Batteries that support SBS are recommended to report the manufacturer name and the device name here."
4075 )]
4076 pub name: ::heapless::Vec<u8, 64>,
4082 }
4083 impl ::emcyphal_encoding::DataType for Parameters {
4084 const EXTENT_BYTES: Option<u32> = Some(300);
4086 }
4087 impl ::emcyphal_encoding::Message for Parameters {}
4088 impl ::emcyphal_encoding::BufferType for Parameters {
4089 type Buffer = ::emcyphal_encoding::StaticBuffer<128>;
4090 }
4091 impl Parameters {}
4092 impl ::emcyphal_encoding::Serialize for Parameters {
4093 fn size_bits(&self) -> usize {
4094 64 + 32
4095 + 32
4096 + (self.design_cell_voltage_min_max).len() * 32
4097 + 32
4098 + 32
4099 + 32
4100 + 32
4101 + 32
4102 + 32
4103 + 16
4104 + 8
4105 + 8
4106 + 7
4107 + 1
4108 + 8
4109 + 32
4110 + 40
4111 + 8
4112 + (self.name).len() * 8
4113 + 0
4114 }
4115 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4116 cursor.write_aligned_u64(self.unique_id);
4117 cursor.write_composite(&self.mass);
4118 cursor.write_composite(&self.design_capacity);
4119 for value in (self.design_cell_voltage_min_max).iter() {
4120 cursor.write_composite(value);
4121 }
4122 cursor.write_composite(&self.discharge_current);
4123 cursor.write_composite(&self.discharge_current_burst);
4124 cursor.write_composite(&self.charge_current);
4125 cursor.write_composite(&self.charge_current_fast);
4126 cursor.write_composite(&self.charge_termination_threshold);
4127 cursor.write_composite(&self.charge_voltage);
4128 cursor.write_aligned_u16(self.cycle_count);
4129 cursor.skip_8();
4130 cursor.write_aligned_u8(self.series_cell_count);
4131 cursor.write_u7(self.state_of_health_pct);
4132 cursor.skip_1();
4133 cursor.write_composite(&self.technology);
4134 cursor.write_composite(&self.nominal_voltage);
4135 cursor.write_u40(self.unix_manufacture_time);
4136 cursor.write_aligned_u8((self.name).len() as u8);
4137 cursor.write_bytes(&(self.name)[..]);
4138 }
4139 }
4140 impl ::emcyphal_encoding::Deserialize for Parameters {
4141 fn deserialize(
4142 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4143 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4144 where
4145 Self: Sized,
4146 {
4147 Ok(Parameters {
4148 unique_id: { cursor.read_u64() as _ },
4149 mass: { cursor.read_composite()? },
4150 design_capacity: { cursor.read_composite()? },
4151 design_cell_voltage_min_max: {
4152 [cursor.read_composite()?, cursor.read_composite()?]
4153 },
4154 discharge_current: { cursor.read_composite()? },
4155 discharge_current_burst: { cursor.read_composite()? },
4156 charge_current: { cursor.read_composite()? },
4157 charge_current_fast: { cursor.read_composite()? },
4158 charge_termination_threshold: { cursor.read_composite()? },
4159 charge_voltage: { cursor.read_composite()? },
4160 cycle_count: { cursor.read_u16() as _ },
4161 series_cell_count: {
4162 cursor.skip_8();
4163 cursor.read_u8() as _
4164 },
4165 state_of_health_pct: { cursor.read_u7() as _ },
4166 technology: {
4167 cursor.skip_1();
4168 cursor.read_composite()?
4169 },
4170 nominal_voltage: { cursor.read_composite()? },
4171 unix_manufacture_time: { cursor.read_u40() as _ },
4172 name: {
4173 let length = cursor.read_u8() as _;
4174 if length <= 64 {
4175 let mut elements = ::heapless::Vec::new();
4176 for _ in 0..length {
4177 let _ = elements.push(cursor.read_u8() as _);
4178 }
4179 elements
4180 } else {
4181 return Err(
4182 ::emcyphal_encoding::DeserializeError::ArrayLength,
4183 );
4184 }
4185 },
4186 })
4187 }
4188 }
4189 }
4190 pub mod status_0_2 {
4191 #[cfg_attr(
4196 not(doctest),
4197 doc = " This low-rate battery status should be published at least once per second."
4198 )]
4199 pub struct Status {
4200 #[cfg_attr(
4201 not(doctest),
4202 doc = " Note that the health code generally should not reflect the battery charge unless the service provider knows\n that the availability of energy in the battery is critical for the safe operation of the vehicle, which is usually\n not the case. For example, if the vehicle is equipped with several batteries that are discharged in series, one\n after another, the depletion of energy in the first battery is not a fault condition and it should not be reported\n as such. This follows from the good service design principles reviewed in https://opencyphal.org/guide.\n\n The readiness state depicts the ability of the battery (or its power electronics) to deliver full rated power\n and whether the overdischarge protections are active.\n When the battery is not ENGAGED, it may limit the output power below the nominal rated value and disconnect the load\n should the charge level fall below the critical level.\n When the battery is ENGAGED, it is not permitted to limit the output power or energy regardless of the risk of damage.\n If the adaptive protection is not supported, the battery should always report its status as ENGAGED."
4203 )]
4204 pub heartbeat: crate::reg::udral::service::common::heartbeat_0_1::Heartbeat,
4210 #[cfg_attr(
4211 not(doctest),
4212 doc = " The minimum and maximum readings of the pack temperature sensors.\n For example, if the pack is equipped with three distributed temperature sensors that read {288, 258.15, 360.5} K,\n the reported array value would be {258.15, 360.5} K.\n If there is only one temperature sensor, both elements shall be of the same value."
4213 )]
4214 pub temperature_min_max:
4220 [crate::uavcan::si::unit::temperature::scalar_1_0::Scalar; 2],
4221 #[cfg_attr(
4222 not(doctest),
4223 doc = " The estimated electric charge currently stored in the battery. This is intended for charging and maintenance only.\n Do not use this parameter for endurance prediction! Instead, use the correct energy type from the physics namespace.\n The depth of discharge (DoD), or the state of charge (SoC), can be derived by dividing this value by the\n nominal battery capacity reported in the Parameters message."
4224 )]
4225 pub available_charge:
4231 crate::uavcan::si::unit::electric_charge::scalar_1_0::Scalar,
4232 pub error: crate::reg::udral::service::battery::error_0_1::Error,
4238 #[cfg_attr(
4239 not(doctest),
4240 doc = " [volt]\n The voltages of individual cells in the battery pack."
4241 )]
4242 pub cell_voltages: ::heapless::Vec<::half::f16, 255>,
4248 }
4249 impl ::emcyphal_encoding::DataType for Status {
4250 const EXTENT_BYTES: Option<u32> = Some(600);
4252 }
4253 impl ::emcyphal_encoding::Message for Status {}
4254 impl ::emcyphal_encoding::BufferType for Status {
4255 type Buffer = ::emcyphal_encoding::StaticBuffer<526>;
4256 }
4257 impl Status {
4258 pub const MAX_CELLS: u8 = 255;
4259 }
4260 impl ::emcyphal_encoding::Serialize for Status {
4261 fn size_bits(&self) -> usize {
4262 16 + (self.temperature_min_max).len() * 32
4263 + 32
4264 + 8
4265 + 8
4266 + (self.cell_voltages).len() * 16
4267 + 0
4268 }
4269 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4270 cursor.write_composite(&self.heartbeat);
4271 for value in (self.temperature_min_max).iter() {
4272 cursor.write_composite(value);
4273 }
4274 cursor.write_composite(&self.available_charge);
4275 cursor.write_composite(&self.error);
4276 cursor.write_aligned_u8((self.cell_voltages).len() as u8);
4277 for value in (self.cell_voltages).iter() {
4278 cursor.write_f16(*value);
4279 }
4280 }
4281 }
4282 impl ::emcyphal_encoding::Deserialize for Status {
4283 fn deserialize(
4284 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4285 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4286 where
4287 Self: Sized,
4288 {
4289 Ok(Status {
4290 heartbeat: { cursor.read_composite()? },
4291 temperature_min_max: {
4292 [cursor.read_composite()?, cursor.read_composite()?]
4293 },
4294 available_charge: { cursor.read_composite()? },
4295 error: { cursor.read_composite()? },
4296 cell_voltages: {
4297 let length = cursor.read_u8() as _;
4298 if length <= 255 {
4299 let mut elements = ::heapless::Vec::new();
4300 for _ in 0..length {
4301 let _ = elements.push(cursor.read_f16());
4302 }
4303 elements
4304 } else {
4305 return Err(
4306 ::emcyphal_encoding::DeserializeError::ArrayLength,
4307 );
4308 }
4309 },
4310 })
4311 }
4312 }
4313 }
4314 pub mod technology_0_1 {
4315 #[cfg_attr(
4320 not(doctest),
4321 doc = " Battery chemistry type and its form-factor.\n Observe that there is no item to represent unknown technology because it is required to be known.\n This information may be used by charging systems to select the appropriate charging strategy.\n If the battery is of an uncommon type, it may be preferred to report the closest-matching type listed here\n instead of OTHER."
4322 )]
4323 #[derive(
4324 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
4325 )]
4326 #[repr(C, packed)]
4327 pub struct Technology {
4328 pub value: u8,
4334 }
4335 impl ::emcyphal_encoding::DataType for Technology {
4336 const EXTENT_BYTES: Option<u32> = None;
4338 }
4339 impl ::emcyphal_encoding::Message for Technology {}
4340 impl ::emcyphal_encoding::BufferType for Technology {
4341 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
4342 }
4343 impl Technology {
4344 #[cfg_attr(
4345 not(doctest),
4346 doc = " The technology is not specified in this enumeration. Please submit a pull request.\n NON-RECHARGEABLE"
4347 )]
4348 pub const OTHER: u8 = 0;
4349 #[cfg_attr(not(doctest), doc = " Lithium-thionyl chloride (Li-SOCl2)")]
4350 pub const LI_SOCL2: u8 = 10;
4351 #[cfg_attr(
4352 not(doctest),
4353 doc = " Lithium-thionyl chloride + bromine chloride (Li-BCX)"
4354 )]
4355 pub const LI_BCX: u8 = 11;
4356 #[cfg_attr(
4357 not(doctest),
4358 doc = " Lithium-manganese dioxide (Li-MnO2) (e.g., lithium coin cell, lithium 9V)"
4359 )]
4360 pub const LI_MNO2: u8 = 12;
4361 #[cfg_attr(not(doctest), doc = " Zinc-Air")]
4362 pub const ZN_O2: u8 = 20;
4363 #[cfg_attr(not(doctest), doc = " Aluminum-Air")]
4364 pub const AL_O2: u8 = 21;
4365 #[cfg_attr(
4366 not(doctest),
4367 doc = " Zinc-manganese dioxide - ammonium chloride electrolyte (aka zinc-carbon)"
4368 )]
4369 pub const ZN_MNO2_NH4CL: u8 = 30;
4370 #[cfg_attr(
4371 not(doctest),
4372 doc = " Zinc-manganese dioxide - zinc chloride electrolyte (aka heavy duty zinc-carbon)"
4373 )]
4374 pub const ZN_MNO2_ZNCL2: u8 = 31;
4375 #[cfg_attr(
4376 not(doctest),
4377 doc = " Zinc-manganese dioxide - potassium hydroxide electrolyte (aka alkaline)\n RECHARGEABLE"
4378 )]
4379 pub const ZN_MNO2_KOH: u8 = 32;
4380 #[cfg_attr(
4381 not(doctest),
4382 doc = " Lithium cobalt oxide (commonly known as just \"lithium-ion\")"
4383 )]
4384 pub const LI_LCO: u8 = 100;
4385 #[cfg_attr(not(doctest), doc = " Lithium iron phosphate (LiFePO4)")]
4386 pub const LI_LFP: u8 = 101;
4387 #[cfg_attr(not(doctest), doc = " Lithium nickel manganese cobalt oxide")]
4388 pub const LI_NMC: u8 = 102;
4389 #[cfg_attr(not(doctest), doc = " Lithium nickel cobalt aluminium oxide")]
4390 pub const LI_NCA: u8 = 103;
4391 #[cfg_attr(not(doctest), doc = " Lithium manganese oxide")]
4392 pub const LI_LMO: u8 = 104;
4393 #[cfg_attr(not(doctest), doc = " Lithium-sulfur (LiS)")]
4394 pub const LI_S: u8 = 105;
4395 #[cfg_attr(
4396 not(doctest),
4397 doc = " LiCoO2 in pouch form factor, commonly known as \"lithium-ion polymer\" or \"LiPo\"."
4398 )]
4399 pub const LI_LCO_POUCH: u8 = 110;
4400 #[cfg_attr(
4401 not(doctest),
4402 doc = " LiFePO4 in pouch form factor, commonly known as \"LiFePO4 polymer\"."
4403 )]
4404 pub const LI_LFP_POUCH: u8 = 111;
4405 #[cfg_attr(not(doctest), doc = " Nickel-metal hydride")]
4406 pub const NI_MH: u8 = 120;
4407 #[cfg_attr(not(doctest), doc = " Nickel-cadmium")]
4408 pub const NI_CD: u8 = 121;
4409 #[cfg_attr(not(doctest), doc = " Nickel-zinc")]
4410 pub const NI_ZN: u8 = 122;
4411 #[cfg_attr(not(doctest), doc = " Nickel-iron")]
4412 pub const NI_FE: u8 = 123;
4413 #[cfg_attr(not(doctest), doc = " Lead acid")]
4414 pub const PB_AC: u8 = 130;
4415 #[cfg_attr(not(doctest), doc = " Also known as SLA")]
4416 pub const PB_AC_SEALED: u8 = 131;
4417 #[cfg_attr(not(doctest), doc = " Electrostatic double-layer capacitor")]
4418 pub const EDLC: u8 = 200;
4419 }
4420 impl ::emcyphal_encoding::Serialize for Technology {
4421 fn size_bits(&self) -> usize {
4422 8
4423 }
4424 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4425 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
4426 }
4427 }
4428 impl ::emcyphal_encoding::Deserialize for Technology {
4429 fn deserialize(
4430 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4431 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4432 where
4433 Self: Sized,
4434 {
4435 Ok(Self::deserialize_zero_copy(cursor))
4436 }
4437 }
4438 #[test]
4439 fn test_layout() {
4440 assert_eq!(::core::mem::size_of::<Technology>() * 8, 8);
4441 assert_eq!(::core::mem::offset_of!(Technology, value) * 8, 0);
4442 }
4443 }
4444 }
4445 pub mod common {
4446 pub mod heartbeat_0_1 {
4447 #[cfg_attr(
4452 not(doctest),
4453 doc = " The function of the service heartbeat is similar to that of the node heartbeat defined in the standard namespace,\n except that it is used on a per-service basis, meaning that there may be more than one publisher per node.\n\n The service heartbeat should be published either on a separate subject, or as a structural supertype of a\n service-specific status subject. The publication rate is service-specific but it should not be lower than 1 Hz.\n\n This is a structural subtype of the Readiness type."
4454 )]
4455 pub struct Heartbeat {
4456 pub readiness: crate::reg::udral::service::common::readiness_0_1::Readiness,
4462 pub health: crate::uavcan::node::health_1_0::Health,
4468 }
4469 impl ::emcyphal_encoding::DataType for Heartbeat {
4470 const EXTENT_BYTES: Option<u32> = None;
4472 }
4473 impl ::emcyphal_encoding::Message for Heartbeat {}
4474 impl ::emcyphal_encoding::BufferType for Heartbeat {
4475 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
4476 }
4477 impl Heartbeat {
4478 #[cfg_attr(
4479 not(doctest),
4480 doc = " Any service that is not in the SLEEP state should publish its heartbeat (or a derived status) at least at this rate."
4481 )]
4482 pub const MAX_PUBLICATION_PERIOD: u8 = 1;
4483 }
4484 impl ::emcyphal_encoding::Serialize for Heartbeat {
4485 fn size_bits(&self) -> usize {
4486 16
4487 }
4488 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4489 cursor.write_composite(&self.readiness);
4490 cursor.write_composite(&self.health);
4491 }
4492 }
4493 impl ::emcyphal_encoding::Deserialize for Heartbeat {
4494 fn deserialize(
4495 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4496 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4497 where
4498 Self: Sized,
4499 {
4500 Ok(Heartbeat {
4501 readiness: { cursor.read_composite()? },
4502 health: { cursor.read_composite()? },
4503 })
4504 }
4505 }
4506 }
4507 pub mod readiness_0_1 {
4508 #[cfg_attr(
4513 not(doctest),
4514 doc = " The readiness state is used to command or report the availability status of a networked service (subsystem).\n\n Any system shall have at least one readiness command subject that acts as a global power switch.\n Every subsystem controlled in such way would usually report its readiness status back to account for the fact that\n the transition between different readiness states may not be instantaneous.\n The readiness status reporting is done by means of the service heartbeat type that is also defined in this namespace;\n the service heartbeat type is a structural subtype of this type.\n\n +------------+\n | Controller |----------+----------------+----------------+---------... readiness command subject\n +------------+ | | |\n ^ ^ ^ v v v\n | | | +---------+ +---------+ +---------+\n | | | | Service | | Service | | Service | ...\n | | | +---------+ +---------+ +---------+\n | | | | | |\n | | +-------------+ | |\n | +----------------------------------+ | service heartbeat subjects\n +-------------------------------------------------------+\n\n In a less trivial use case there may be an arbitrary number of such readiness command subjects (local power switches)\n controlling various systems within the vehicle (e.g., propulsion, perception sensors, communication, etc).\n\n The publication rate is defined on a per-service basis, but it should never be lower than 1 Hz,\n excepting services that are in the SLEEP state, in which case it is permitted to cease all network activity."
4515 )]
4516 pub struct Readiness {
4517 pub value: u8,
4523 }
4524 impl ::emcyphal_encoding::DataType for Readiness {
4525 const EXTENT_BYTES: Option<u32> = None;
4527 }
4528 impl ::emcyphal_encoding::Message for Readiness {}
4529 impl ::emcyphal_encoding::BufferType for Readiness {
4530 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
4531 }
4532 impl Readiness {
4533 #[cfg_attr(
4534 not(doctest),
4535 doc = " The long-term state of minimal power consumption.\n Typically, most subsystems are switched into the SLEEP mode when the vehicle is parked and powered off.\n Subsystems that do not support the SLEEP state should treat it as an equivalent of STANDBY.\n\n A subsystem may require a substantial amount of time to exit the sleep mode (for example, time may be needed to\n boot the operating system and run the self test procedures).\n\n While in the SLEEP mode, the subsystem is allowed to cease service provision and stop all network activity\n regardless of other requirements, except that it shall be able to reactivate itself if a Readiness message is\n received commanding any state other than SLEEP.\n Value 1 is invalid and shall never be commanded.\n Implementations receiving this value should interpret it either as SLEEP or STANDBY."
4536 )]
4537 pub const SLEEP: u8 = 0;
4538 #[cfg_attr(
4539 not(doctest),
4540 doc = " The state of being ready to enter the normal operating mode in a short order.\n A subsystem that is in STANDBY state should be able to participate in the normal network activity.\n This is the default state that the subsystem should reside in after power-on until explicitly commanded otherwise."
4541 )]
4542 pub const STANDBY: u8 = 2;
4543 #[cfg_attr(
4544 not(doctest),
4545 doc = " When ENGAGED, the subsystem is performing its main intended function at the nominal performance characteristics.\n A subsystem may require a short amount of time, possibly under a few seconds, to switch between the ENGAGED and\n STANDBY states (in any direction).\n Some subsystems may not differentiate between STANDBY and ENGAGED (e.g., offboard communication hardware).\n The subsystem may disengage itself autonomously in the event of a fatal malfunction, in which case\n the reported service health status should be WARNING."
4546 )]
4547 pub const ENGAGED: u8 = 3;
4548 }
4549 impl ::emcyphal_encoding::Serialize for Readiness {
4550 fn size_bits(&self) -> usize {
4551 8
4552 }
4553 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4554 cursor.write_u2(self.value);
4555 }
4556 }
4557 impl ::emcyphal_encoding::Deserialize for Readiness {
4558 fn deserialize(
4559 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4560 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4561 where
4562 Self: Sized,
4563 {
4564 Ok(Readiness {
4565 value: { cursor.read_u2() as _ },
4566 })
4567 }
4568 }
4569 }
4570 }
4571 pub mod sensor {
4572 pub mod status_0_1 {
4573 #[cfg_attr(
4578 not(doctest),
4579 doc = " A generic sensor status information.\n This data should be published at a low rate but not lower than the specified limit."
4580 )]
4581 #[derive(
4582 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
4583 )]
4584 #[repr(C, packed)]
4585 pub struct Status {
4586 #[cfg_attr(
4587 not(doctest),
4588 doc = " Data samples obtained at time Ts are valid at time Tr if: (Tr - Ts) < data_validity_period\n Expired data should be discarded."
4589 )]
4590 pub data_validity_period:
4596 crate::uavcan::si::unit::duration::scalar_1_0::Scalar,
4597 #[cfg_attr(
4598 not(doctest),
4599 doc = " Incremented once per occurrence. Reset to zero when the sensor is ENGAGED.\n The exact definition of what constitutes an error is implementation-dependent."
4600 )]
4601 pub error_count: u32,
4607 #[cfg_attr(
4608 not(doctest),
4609 doc = " The temperature of the sensing element.\n If there are multiple sensing elements or multiple temperature probes per sensor,\n the reduction is implementation-defined.\n In a later revision this field may be moved into a separate type."
4610 )]
4611 pub sensor_temperature:
4617 crate::uavcan::si::unit::temperature::scalar_1_0::Scalar,
4618 }
4619 impl ::emcyphal_encoding::DataType for Status {
4620 const EXTENT_BYTES: Option<u32> = Some(63);
4622 }
4623 impl ::emcyphal_encoding::Message for Status {}
4624 impl ::emcyphal_encoding::BufferType for Status {
4625 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
4626 }
4627 impl Status {
4628 #[cfg_attr(not(doctest), doc = " [second]")]
4629 pub const MAX_PUBLICATION_PERIOD: u8 = 1;
4630 }
4631 impl ::emcyphal_encoding::Serialize for Status {
4632 fn size_bits(&self) -> usize {
4633 96
4634 }
4635 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4636 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
4637 }
4638 }
4639 impl ::emcyphal_encoding::Deserialize for Status {
4640 fn deserialize(
4641 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4642 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4643 where
4644 Self: Sized,
4645 {
4646 Ok(Self::deserialize_zero_copy(cursor))
4647 }
4648 }
4649 #[test]
4650 fn test_layout() {
4651 assert_eq!(::core::mem::size_of::<Status>() * 8, 96);
4652 assert_eq!(::core::mem::offset_of!(Status, data_validity_period) * 8, 0);
4653 assert_eq!(::core::mem::offset_of!(Status, error_count) * 8, 32);
4654 assert_eq!(::core::mem::offset_of!(Status, sensor_temperature) * 8, 64);
4655 }
4656 }
4657 }
4658 }
4659 }
4660}
4661#[allow(unused_variables, unused_braces, unused_parens)]
4662#[allow(clippy::identity_op)]
4663pub mod uavcan {
4664 pub mod diagnostic {
4665 #[allow(deprecated)]
4666 #[cfg_attr(not(test), deprecated)]
4667 pub mod record_1_0 {
4668 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
4669 #[deprecated]
4670 pub const SUBJECT: ::emcyphal_core::SubjectId =
4671 ::emcyphal_core::SubjectId::from_u16_truncating(8184);
4672
4673 #[cfg_attr(
4678 not(doctest),
4679 doc = " Generic human-readable text message for logging and displaying purposes.\n Generally, it should be published at the lowest priority level."
4680 )]
4681 #[deprecated]
4682 pub struct Record {
4683 #[cfg_attr(
4684 not(doctest),
4685 doc = " Optional timestamp in the network-synchronized time system; zero if undefined.\n The timestamp value conveys the exact moment when the reported event took place."
4686 )]
4687 pub timestamp:
4693 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
4694 pub severity: crate::uavcan::diagnostic::severity_1_0::Severity,
4700 #[cfg_attr(
4701 not(doctest),
4702 doc = " Message text.\n Normally, messages should be kept as short as possible, especially those of high severity."
4703 )]
4704 pub text: ::heapless::Vec<u8, 112>,
4710 }
4711 impl ::emcyphal_encoding::DataType for Record {
4712 const EXTENT_BYTES: Option<u32> = Some(300);
4714 }
4715 impl ::emcyphal_encoding::Message for Record {}
4716 impl ::emcyphal_encoding::BufferType for Record {
4717 type Buffer = ::emcyphal_encoding::StaticBuffer<121>;
4718 }
4719 impl Record {}
4720 impl ::emcyphal_encoding::Serialize for Record {
4721 fn size_bits(&self) -> usize {
4722 56 + 8 + 8 + (self.text).len() * 8 + 0
4723 }
4724 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4725 cursor.write_composite(&self.timestamp);
4726 cursor.write_composite(&self.severity);
4727 cursor.write_aligned_u8((self.text).len() as u8);
4728 cursor.write_bytes(&(self.text)[..]);
4729 }
4730 }
4731 impl ::emcyphal_encoding::Deserialize for Record {
4732 fn deserialize(
4733 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4734 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4735 where
4736 Self: Sized,
4737 {
4738 Ok(Record {
4739 timestamp: { cursor.read_composite()? },
4740 severity: { cursor.read_composite()? },
4741 text: {
4742 let length = cursor.read_u8() as _;
4743 if length <= 112 {
4744 let mut elements = ::heapless::Vec::new();
4745 for _ in 0..length {
4746 let _ = elements.push(cursor.read_u8() as _);
4747 }
4748 elements
4749 } else {
4750 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
4751 }
4752 },
4753 })
4754 }
4755 }
4756 }
4757 pub mod record_1_1 {
4758 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
4759 pub const SUBJECT: ::emcyphal_core::SubjectId =
4760 ::emcyphal_core::SubjectId::from_u16_truncating(8184);
4761
4762 #[cfg_attr(
4767 not(doctest),
4768 doc = " Generic human-readable text message for logging and displaying purposes.\n Generally, it should be published at the lowest priority level."
4769 )]
4770 pub struct Record {
4771 #[cfg_attr(
4772 not(doctest),
4773 doc = " Optional timestamp in the network-synchronized time system; zero if undefined.\n The timestamp value conveys the exact moment when the reported event took place."
4774 )]
4775 pub timestamp:
4781 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
4782 pub severity: crate::uavcan::diagnostic::severity_1_0::Severity,
4788 #[cfg_attr(
4789 not(doctest),
4790 doc = " Message text.\n Normally, messages should be kept as short as possible, especially those of high severity."
4791 )]
4792 pub text: ::heapless::Vec<u8, 255>,
4798 }
4799 impl ::emcyphal_encoding::DataType for Record {
4800 const EXTENT_BYTES: Option<u32> = Some(300);
4802 }
4803 impl ::emcyphal_encoding::Message for Record {}
4804 impl ::emcyphal_encoding::BufferType for Record {
4805 type Buffer = ::emcyphal_encoding::StaticBuffer<264>;
4806 }
4807 impl Record {}
4808 impl ::emcyphal_encoding::Serialize for Record {
4809 fn size_bits(&self) -> usize {
4810 56 + 8 + 8 + (self.text).len() * 8 + 0
4811 }
4812 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4813 cursor.write_composite(&self.timestamp);
4814 cursor.write_composite(&self.severity);
4815 cursor.write_aligned_u8((self.text).len() as u8);
4816 cursor.write_bytes(&(self.text)[..]);
4817 }
4818 }
4819 impl ::emcyphal_encoding::Deserialize for Record {
4820 fn deserialize(
4821 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4822 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4823 where
4824 Self: Sized,
4825 {
4826 Ok(Record {
4827 timestamp: { cursor.read_composite()? },
4828 severity: { cursor.read_composite()? },
4829 text: {
4830 let length = cursor.read_u8() as _;
4831 if length <= 255 {
4832 let mut elements = ::heapless::Vec::new();
4833 for _ in 0..length {
4834 let _ = elements.push(cursor.read_u8() as _);
4835 }
4836 elements
4837 } else {
4838 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
4839 }
4840 },
4841 })
4842 }
4843 }
4844 }
4845 pub mod severity_1_0 {
4846 #[cfg_attr(not(doctest), doc = " Generic message severity representation.")]
4851 pub struct Severity {
4852 #[cfg_attr(
4853 not(doctest),
4854 doc = " The severity level ranging from 0 to 7, where low values represent low-severity (unimportant) messages, and\n high values represent high-severity (important) messages. Several mnemonics for the severity levels are\n defined below. Nodes are advised to implement output filtering mechanisms, allowing users to select\n the minimal severity for emitted messages; messages of the selected and higher severity levels will\n be published, and messages of lower severity will be suppressed (discarded)."
4855 )]
4856 pub value: u8,
4862 }
4863 impl ::emcyphal_encoding::DataType for Severity {
4864 const EXTENT_BYTES: Option<u32> = None;
4866 }
4867 impl ::emcyphal_encoding::Message for Severity {}
4868 impl ::emcyphal_encoding::BufferType for Severity {
4869 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
4870 }
4871 impl Severity {
4872 #[cfg_attr(
4873 not(doctest),
4874 doc = " Messages of this severity can be used only during development.\n They shall not be used in a fielded operational system."
4875 )]
4876 pub const TRACE: u8 = 0;
4877 #[cfg_attr(
4878 not(doctest),
4879 doc = " Messages that can aid in troubleshooting.\n Messages of this severity and lower should be disabled by default."
4880 )]
4881 pub const DEBUG: u8 = 1;
4882 #[cfg_attr(
4883 not(doctest),
4884 doc = " General informational messages of low importance.\n Messages of this severity and lower should be disabled by default."
4885 )]
4886 pub const INFO: u8 = 2;
4887 #[cfg_attr(
4888 not(doctest),
4889 doc = " General informational messages of high importance.\n Messages of this severity and lower should be disabled by default."
4890 )]
4891 pub const NOTICE: u8 = 3;
4892 #[cfg_attr(
4893 not(doctest),
4894 doc = " Messages reporting abnormalities and warning conditions.\n Messages of this severity and higher should be enabled by default."
4895 )]
4896 pub const WARNING: u8 = 4;
4897 #[cfg_attr(
4898 not(doctest),
4899 doc = " Messages reporting problems and error conditions.\n Messages of this severity and higher should be enabled by default."
4900 )]
4901 pub const ERROR: u8 = 5;
4902 #[cfg_attr(
4903 not(doctest),
4904 doc = " Messages reporting serious problems and critical conditions.\n Messages of this severity and higher should be always enabled."
4905 )]
4906 pub const CRITICAL: u8 = 6;
4907 #[cfg_attr(
4908 not(doctest),
4909 doc = " Notifications of dangerous circumstances that demand immediate attention.\n Messages of this severity should be always enabled."
4910 )]
4911 pub const ALERT: u8 = 7;
4912 }
4913 impl ::emcyphal_encoding::Serialize for Severity {
4914 fn size_bits(&self) -> usize {
4915 8
4916 }
4917 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4918 cursor.write_u3(self.value);
4919 }
4920 }
4921 impl ::emcyphal_encoding::Deserialize for Severity {
4922 fn deserialize(
4923 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4924 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4925 where
4926 Self: Sized,
4927 {
4928 Ok(Severity {
4929 value: { cursor.read_u3() as _ },
4930 })
4931 }
4932 }
4933 }
4934 }
4935 pub mod file {
4936 pub mod error_1_0 {
4937 #[cfg_attr(
4942 not(doctest),
4943 doc = " Nested type.\n Result of a file system operation."
4944 )]
4945 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
4946 #[repr(C, packed)]
4947 pub struct Error {
4948 pub value: u16,
4954 }
4955 impl ::emcyphal_encoding::DataType for Error {
4956 const EXTENT_BYTES: Option<u32> = None;
4958 }
4959 impl ::emcyphal_encoding::Message for Error {}
4960 impl ::emcyphal_encoding::BufferType for Error {
4961 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
4962 }
4963 impl Error {
4964 pub const OK: u16 = 0;
4965 pub const UNKNOWN_ERROR: u16 = 65535;
4966 pub const NOT_FOUND: u16 = 2;
4967 pub const IO_ERROR: u16 = 5;
4968 pub const ACCESS_DENIED: u16 = 13;
4969 #[cfg_attr(
4970 not(doctest),
4971 doc = " I.e., attempted read/write on a path that points to a directory"
4972 )]
4973 pub const IS_DIRECTORY: u16 = 21;
4974 #[cfg_attr(
4975 not(doctest),
4976 doc = " E.g., file name is not valid for the target file system"
4977 )]
4978 pub const INVALID_VALUE: u16 = 22;
4979 pub const FILE_TOO_LARGE: u16 = 27;
4980 pub const OUT_OF_SPACE: u16 = 28;
4981 pub const NOT_SUPPORTED: u16 = 38;
4982 }
4983 impl ::emcyphal_encoding::Serialize for Error {
4984 fn size_bits(&self) -> usize {
4985 16
4986 }
4987 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
4988 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
4989 }
4990 }
4991 impl ::emcyphal_encoding::Deserialize for Error {
4992 fn deserialize(
4993 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
4994 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
4995 where
4996 Self: Sized,
4997 {
4998 Ok(Self::deserialize_zero_copy(cursor))
4999 }
5000 }
5001 #[test]
5002 fn test_layout() {
5003 assert_eq!(::core::mem::size_of::<Error>() * 8, 16);
5004 assert_eq!(::core::mem::offset_of!(Error, value) * 8, 0);
5005 }
5006 }
5007 #[allow(deprecated)]
5008 #[cfg_attr(not(test), deprecated)]
5009 pub mod get_info_0_1 {
5010 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5011 #[deprecated]
5012 pub const SERVICE: ::emcyphal_core::ServiceId =
5013 ::emcyphal_core::ServiceId::from_u16_truncating(405);
5014
5015 #[cfg_attr(
5020 not(doctest),
5021 doc = " Information about a remote file system entry (file, directory, etc)."
5022 )]
5023 #[deprecated]
5024 pub struct GetInfoRequest {
5025 pub path: crate::uavcan::file::path_1_0::Path,
5031 }
5032 impl ::emcyphal_encoding::DataType for GetInfoRequest {
5033 const EXTENT_BYTES: Option<u32> = Some(300);
5035 }
5036 impl ::emcyphal_encoding::Request for GetInfoRequest {}
5037 impl ::emcyphal_encoding::BufferType for GetInfoRequest {
5038 type Buffer = ::emcyphal_encoding::StaticBuffer<113>;
5039 }
5040 impl GetInfoRequest {}
5041 impl ::emcyphal_encoding::Serialize for GetInfoRequest {
5042 fn size_bits(&self) -> usize {
5043 (self.path).size_bits() + 0
5044 }
5045 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5046 cursor.write_composite(&self.path);
5047 }
5048 }
5049 impl ::emcyphal_encoding::Deserialize for GetInfoRequest {
5050 fn deserialize(
5051 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5052 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5053 where
5054 Self: Sized,
5055 {
5056 Ok(GetInfoRequest {
5057 path: { cursor.read_composite()? },
5058 })
5059 }
5060 }
5061
5062 #[deprecated]
5067 pub struct GetInfoResponse {
5068 #[cfg_attr(not(doctest), doc = " Result of the operation.")]
5069 pub error: crate::uavcan::file::error_1_0::Error,
5075 #[cfg_attr(
5076 not(doctest),
5077 doc = " File size in bytes. Should be set to zero for directories."
5078 )]
5079 pub size: u64,
5085 #[cfg_attr(
5086 not(doctest),
5087 doc = " The UNIX Epoch time when the entry was last modified. Zero if unknown."
5088 )]
5089 pub unix_timestamp_of_last_modification: u64,
5095 #[cfg_attr(not(doctest), doc = " True if file, false if directory.")]
5096 pub is_file_not_directory: bool,
5102 #[cfg_attr(
5103 not(doctest),
5104 doc = " This is a link to another entry; the above flag indicates the type of the target."
5105 )]
5106 pub is_link: bool,
5112 #[cfg_attr(
5113 not(doctest),
5114 doc = " The item can be read by the caller (applies to files and directories)."
5115 )]
5116 pub is_readable: bool,
5122 #[cfg_attr(
5123 not(doctest),
5124 doc = " The item can be written by the caller (applies to files and directories).\n If such entry does not exist, all flags should be cleared/ignored."
5125 )]
5126 pub is_writeable: bool,
5132 }
5134 impl ::emcyphal_encoding::DataType for GetInfoResponse {
5135 const EXTENT_BYTES: Option<u32> = Some(48);
5137 }
5138 impl ::emcyphal_encoding::Response for GetInfoResponse {}
5139 impl ::emcyphal_encoding::BufferType for GetInfoResponse {
5140 type Buffer = ::emcyphal_encoding::StaticBuffer<13>;
5141 }
5142 impl GetInfoResponse {}
5143 impl ::emcyphal_encoding::Serialize for GetInfoResponse {
5144 fn size_bits(&self) -> usize {
5145 104
5146 }
5147 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5148 cursor.write_composite(&self.error);
5149 cursor.write_u40(self.size);
5150 cursor.write_u40(self.unix_timestamp_of_last_modification);
5151 cursor.write_bool(self.is_file_not_directory);
5152 cursor.write_bool(self.is_link);
5153 cursor.write_bool(self.is_readable);
5154 cursor.write_bool(self.is_writeable);
5155 cursor.skip_4();
5156 }
5157 }
5158 impl ::emcyphal_encoding::Deserialize for GetInfoResponse {
5159 fn deserialize(
5160 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5161 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5162 where
5163 Self: Sized,
5164 {
5165 Ok(GetInfoResponse {
5166 error: { cursor.read_composite()? },
5167 size: { cursor.read_u40() as _ },
5168 unix_timestamp_of_last_modification: { cursor.read_u40() as _ },
5169 is_file_not_directory: { cursor.read_bool() },
5170 is_link: { cursor.read_bool() },
5171 is_readable: { cursor.read_bool() },
5172 is_writeable: { cursor.read_bool() },
5173 })
5174 }
5175 }
5176 }
5177 pub mod get_info_0_2 {
5178 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5179 pub const SERVICE: ::emcyphal_core::ServiceId =
5180 ::emcyphal_core::ServiceId::from_u16_truncating(405);
5181
5182 #[cfg_attr(
5187 not(doctest),
5188 doc = " Information about a remote file system entry (file, directory, etc)."
5189 )]
5190 pub struct GetInfoRequest {
5191 pub path: crate::uavcan::file::path_2_0::Path,
5197 }
5198 impl ::emcyphal_encoding::DataType for GetInfoRequest {
5199 const EXTENT_BYTES: Option<u32> = Some(300);
5201 }
5202 impl ::emcyphal_encoding::Request for GetInfoRequest {}
5203 impl ::emcyphal_encoding::BufferType for GetInfoRequest {
5204 type Buffer = ::emcyphal_encoding::StaticBuffer<256>;
5205 }
5206 impl GetInfoRequest {}
5207 impl ::emcyphal_encoding::Serialize for GetInfoRequest {
5208 fn size_bits(&self) -> usize {
5209 (self.path).size_bits() + 0
5210 }
5211 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5212 cursor.write_composite(&self.path);
5213 }
5214 }
5215 impl ::emcyphal_encoding::Deserialize for GetInfoRequest {
5216 fn deserialize(
5217 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5218 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5219 where
5220 Self: Sized,
5221 {
5222 Ok(GetInfoRequest {
5223 path: { cursor.read_composite()? },
5224 })
5225 }
5226 }
5227
5228 pub struct GetInfoResponse {
5233 #[cfg_attr(not(doctest), doc = " Result of the operation.")]
5234 pub error: crate::uavcan::file::error_1_0::Error,
5240 #[cfg_attr(
5241 not(doctest),
5242 doc = " File size in bytes. Should be set to zero for directories."
5243 )]
5244 pub size: u64,
5250 #[cfg_attr(
5251 not(doctest),
5252 doc = " The UNIX Epoch time when the entry was last modified. Zero if unknown."
5253 )]
5254 pub unix_timestamp_of_last_modification: u64,
5260 #[cfg_attr(not(doctest), doc = " True if file, false if directory.")]
5261 pub is_file_not_directory: bool,
5267 #[cfg_attr(
5268 not(doctest),
5269 doc = " This is a link to another entry; the above flag indicates the type of the target."
5270 )]
5271 pub is_link: bool,
5277 #[cfg_attr(
5278 not(doctest),
5279 doc = " The item can be read by the caller (applies to files and directories)."
5280 )]
5281 pub is_readable: bool,
5287 #[cfg_attr(
5288 not(doctest),
5289 doc = " The item can be written by the caller (applies to files and directories).\n If such entry does not exist, all flags should be cleared/ignored."
5290 )]
5291 pub is_writeable: bool,
5297 }
5299 impl ::emcyphal_encoding::DataType for GetInfoResponse {
5300 const EXTENT_BYTES: Option<u32> = Some(48);
5302 }
5303 impl ::emcyphal_encoding::Response for GetInfoResponse {}
5304 impl ::emcyphal_encoding::BufferType for GetInfoResponse {
5305 type Buffer = ::emcyphal_encoding::StaticBuffer<13>;
5306 }
5307 impl GetInfoResponse {}
5308 impl ::emcyphal_encoding::Serialize for GetInfoResponse {
5309 fn size_bits(&self) -> usize {
5310 104
5311 }
5312 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5313 cursor.write_composite(&self.error);
5314 cursor.write_u40(self.size);
5315 cursor.write_u40(self.unix_timestamp_of_last_modification);
5316 cursor.write_bool(self.is_file_not_directory);
5317 cursor.write_bool(self.is_link);
5318 cursor.write_bool(self.is_readable);
5319 cursor.write_bool(self.is_writeable);
5320 cursor.skip_4();
5321 }
5322 }
5323 impl ::emcyphal_encoding::Deserialize for GetInfoResponse {
5324 fn deserialize(
5325 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5326 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5327 where
5328 Self: Sized,
5329 {
5330 Ok(GetInfoResponse {
5331 error: { cursor.read_composite()? },
5332 size: { cursor.read_u40() as _ },
5333 unix_timestamp_of_last_modification: { cursor.read_u40() as _ },
5334 is_file_not_directory: { cursor.read_bool() },
5335 is_link: { cursor.read_bool() },
5336 is_readable: { cursor.read_bool() },
5337 is_writeable: { cursor.read_bool() },
5338 })
5339 }
5340 }
5341 }
5342 #[allow(deprecated)]
5343 #[cfg_attr(not(test), deprecated)]
5344 pub mod list_0_1 {
5345 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5346 #[deprecated]
5347 pub const SERVICE: ::emcyphal_core::ServiceId =
5348 ::emcyphal_core::ServiceId::from_u16_truncating(406);
5349
5350 #[cfg_attr(
5355 not(doctest),
5356 doc = " This service can be used to list a remote directory, one entry per request.\n\n The client should query each entry independently, iterating 'entry_index' from 0 until the last entry.\n When the index reaches the number of elements in the directory, the server will report that there is\n no such entry by returning an empty name.\n\n The field entry_index shall be applied to an ordered list of directory entries (e.g. alphabetically ordered).\n The exact sorting criteria does not matter as long as it provides the same ordering for subsequent service calls.\n\n Observe that this listing operation is fundamentally non-atomic. The caller shall beware of possible race conditions\n and is responsible for handling them properly. Particularly, consider what happens if a new item is inserted into\n the directory between two subsequent calls: if the item happened to be inserted at the index that is lower than the\n index of the next request, the next returned item (or several, if more items were inserted) will repeat the ones\n that were listed earlier. The caller should handle that properly, either by ignoring the repeated items or by\n restarting the listing operation from the beginning (index 0)."
5357 )]
5358 #[deprecated]
5359 pub struct ListRequest {
5360 pub entry_index: u32,
5366 pub directory_path: crate::uavcan::file::path_1_0::Path,
5373 }
5374 impl ::emcyphal_encoding::DataType for ListRequest {
5375 const EXTENT_BYTES: Option<u32> = Some(300);
5377 }
5378 impl ::emcyphal_encoding::Request for ListRequest {}
5379 impl ::emcyphal_encoding::BufferType for ListRequest {
5380 type Buffer = ::emcyphal_encoding::StaticBuffer<121>;
5381 }
5382 impl ListRequest {}
5383 impl ::emcyphal_encoding::Serialize for ListRequest {
5384 fn size_bits(&self) -> usize {
5385 32 + 32 + (self.directory_path).size_bits() + 0
5386 }
5387 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5388 cursor.write_aligned_u32(self.entry_index);
5389 cursor.skip_32();
5390 cursor.write_composite(&self.directory_path);
5391 }
5392 }
5393 impl ::emcyphal_encoding::Deserialize for ListRequest {
5394 fn deserialize(
5395 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5396 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5397 where
5398 Self: Sized,
5399 {
5400 Ok(ListRequest {
5401 entry_index: { cursor.read_u32() as _ },
5402 directory_path: {
5403 cursor.skip_32();
5404 cursor.read_composite()?
5405 },
5406 })
5407 }
5408 }
5409
5410 #[deprecated]
5415 pub struct ListResponse {
5416 #[cfg_attr(
5418 not(doctest),
5419 doc = " The base name of the referenced entry, i.e., relative to the outer directory.\n The outer directory path is not included to conserve bandwidth.\n Empty if such entry does not exist.\n\n For example, suppose there is a file \"/foo/bar/baz.bin\". Listing the directory with the path \"/foo/bar/\" (the slash\n at the end is optional) at the index 0 will return \"baz.bin\". Listing the same directory at the index 1 (or any\n higher) will return an empty name \"\", indicating that the caller has reached the end of the list."
5420 )]
5421 pub entry_base_name: crate::uavcan::file::path_1_0::Path,
5427 }
5428 impl ::emcyphal_encoding::DataType for ListResponse {
5429 const EXTENT_BYTES: Option<u32> = Some(300);
5431 }
5432 impl ::emcyphal_encoding::Response for ListResponse {}
5433 impl ::emcyphal_encoding::BufferType for ListResponse {
5434 type Buffer = ::emcyphal_encoding::StaticBuffer<117>;
5435 }
5436 impl ListResponse {}
5437 impl ::emcyphal_encoding::Serialize for ListResponse {
5438 fn size_bits(&self) -> usize {
5439 32 + (self.entry_base_name).size_bits() + 0
5440 }
5441 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5442 cursor.skip_32();
5443 cursor.write_composite(&self.entry_base_name);
5444 }
5445 }
5446 impl ::emcyphal_encoding::Deserialize for ListResponse {
5447 fn deserialize(
5448 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5449 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5450 where
5451 Self: Sized,
5452 {
5453 Ok(ListResponse {
5454 entry_base_name: {
5455 cursor.skip_32();
5456 cursor.read_composite()?
5457 },
5458 })
5459 }
5460 }
5461 }
5462 pub mod list_0_2 {
5463 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5464 pub const SERVICE: ::emcyphal_core::ServiceId =
5465 ::emcyphal_core::ServiceId::from_u16_truncating(406);
5466
5467 #[cfg_attr(
5472 not(doctest),
5473 doc = " This service can be used to list a remote directory, one entry per request.\n\n The client should query each entry independently, iterating 'entry_index' from 0 until the last entry.\n When the index reaches the number of elements in the directory, the server will report that there is\n no such entry by returning an empty name.\n\n The field entry_index shall be applied to an ordered list of directory entries (e.g. alphabetically ordered).\n The exact sorting criteria does not matter as long as it provides the same ordering for subsequent service calls.\n\n Observe that this listing operation is fundamentally non-atomic. The caller shall beware of possible race conditions\n and is responsible for handling them properly. Particularly, consider what happens if a new item is inserted into\n the directory between two subsequent calls: if the item happened to be inserted at the index that is lower than the\n index of the next request, the next returned item (or several, if more items were inserted) will repeat the ones\n that were listed earlier. The caller should handle that properly, either by ignoring the repeated items or by\n restarting the listing operation from the beginning (index 0)."
5474 )]
5475 pub struct ListRequest {
5476 pub entry_index: u32,
5482 pub directory_path: crate::uavcan::file::path_2_0::Path,
5489 }
5490 impl ::emcyphal_encoding::DataType for ListRequest {
5491 const EXTENT_BYTES: Option<u32> = Some(300);
5493 }
5494 impl ::emcyphal_encoding::Request for ListRequest {}
5495 impl ::emcyphal_encoding::BufferType for ListRequest {
5496 type Buffer = ::emcyphal_encoding::StaticBuffer<264>;
5497 }
5498 impl ListRequest {}
5499 impl ::emcyphal_encoding::Serialize for ListRequest {
5500 fn size_bits(&self) -> usize {
5501 32 + 32 + (self.directory_path).size_bits() + 0
5502 }
5503 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5504 cursor.write_aligned_u32(self.entry_index);
5505 cursor.skip_32();
5506 cursor.write_composite(&self.directory_path);
5507 }
5508 }
5509 impl ::emcyphal_encoding::Deserialize for ListRequest {
5510 fn deserialize(
5511 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5512 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5513 where
5514 Self: Sized,
5515 {
5516 Ok(ListRequest {
5517 entry_index: { cursor.read_u32() as _ },
5518 directory_path: {
5519 cursor.skip_32();
5520 cursor.read_composite()?
5521 },
5522 })
5523 }
5524 }
5525
5526 pub struct ListResponse {
5531 #[cfg_attr(
5533 not(doctest),
5534 doc = " The base name of the referenced entry, i.e., relative to the outer directory.\n The outer directory path is not included to conserve bandwidth.\n Empty if such entry does not exist.\n\n For example, suppose there is a file \"/foo/bar/baz.bin\". Listing the directory with the path \"/foo/bar/\" (the slash\n at the end is optional) at the index 0 will return \"baz.bin\". Listing the same directory at the index 1 (or any\n higher) will return an empty name \"\", indicating that the caller has reached the end of the list."
5535 )]
5536 pub entry_base_name: crate::uavcan::file::path_2_0::Path,
5542 }
5543 impl ::emcyphal_encoding::DataType for ListResponse {
5544 const EXTENT_BYTES: Option<u32> = Some(300);
5546 }
5547 impl ::emcyphal_encoding::Response for ListResponse {}
5548 impl ::emcyphal_encoding::BufferType for ListResponse {
5549 type Buffer = ::emcyphal_encoding::StaticBuffer<260>;
5550 }
5551 impl ListResponse {}
5552 impl ::emcyphal_encoding::Serialize for ListResponse {
5553 fn size_bits(&self) -> usize {
5554 32 + (self.entry_base_name).size_bits() + 0
5555 }
5556 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5557 cursor.skip_32();
5558 cursor.write_composite(&self.entry_base_name);
5559 }
5560 }
5561 impl ::emcyphal_encoding::Deserialize for ListResponse {
5562 fn deserialize(
5563 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5564 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5565 where
5566 Self: Sized,
5567 {
5568 Ok(ListResponse {
5569 entry_base_name: {
5570 cursor.skip_32();
5571 cursor.read_composite()?
5572 },
5573 })
5574 }
5575 }
5576 }
5577 #[allow(deprecated)]
5578 #[cfg_attr(not(test), deprecated)]
5579 pub mod modify_1_0 {
5580 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5581 #[deprecated]
5582 pub const SERVICE: ::emcyphal_core::ServiceId =
5583 ::emcyphal_core::ServiceId::from_u16_truncating(407);
5584
5585 #[cfg_attr(
5590 not(doctest),
5591 doc = " Manipulate a remote file system entry. Applies to files, directories, and links alike.\n If the remote entry is a directory, all nested entries will be affected, too.\n\n The server should perform all operations atomically, unless atomicity is not supported by\n the underlying file system.\n\n Atomic copying can be effectively employed by remote nodes before reading or after writing\n the file to minimize the possibility of race conditions.\n For example, before reading a large file from the server, the cilent might opt to create\n a temporary copy of it first, then read the copy, and delete it upon completion. Likewise,\n a similar strategy can be employed for writing, where the file is first written at a\n temporary location, and then moved to its final destination. These approaches, however,\n may lead to creation of dangling temporary files if the client failed to dispose of them\n properly, so that risk should be taken into account.\n\n Move/Copy\n Specify the source path and the destination path.\n If the source does not exist, the operation will fail.\n Set the preserve_source flag to copy rather than move.\n If the destination exists and overwrite_destination is not set, the operation will fail.\n If the target path includes non-existent directories, they will be created (like \"mkdir -p\").\n\n Touch\n Specify the destination path and make the source path empty.\n If the path exists (file/directory/link), its modification time will be updated.\n If the path does not exist, an empty file will be created.\n If the target path includes non-existent directories, they will be created (like \"mkdir -p\").\n Flags are ignored.\n\n Remove\n Specify the source path (file/directory/link) and make the destination path empty.\n Fails if the path does not exist.\n Flags are ignored."
5592 )]
5593 #[deprecated]
5594 pub struct ModifyRequest {
5595 #[cfg_attr(
5596 not(doctest),
5597 doc = " Do not remove the source. Used to copy instead of moving."
5598 )]
5599 pub preserve_source: bool,
5605 #[cfg_attr(
5606 not(doctest),
5607 doc = " If the destination exists, remove it beforehand."
5608 )]
5609 pub overwrite_destination: bool,
5615 pub source: crate::uavcan::file::path_1_0::Path,
5622 pub destination: crate::uavcan::file::path_1_0::Path,
5628 }
5629 impl ::emcyphal_encoding::DataType for ModifyRequest {
5630 const EXTENT_BYTES: Option<u32> = Some(600);
5632 }
5633 impl ::emcyphal_encoding::Request for ModifyRequest {}
5634 impl ::emcyphal_encoding::BufferType for ModifyRequest {
5635 type Buffer = ::emcyphal_encoding::StaticBuffer<230>;
5636 }
5637 impl ModifyRequest {}
5638 impl ::emcyphal_encoding::Serialize for ModifyRequest {
5639 fn size_bits(&self) -> usize {
5640 1 + 1 + 30 + (self.source).size_bits() + (self.destination).size_bits() + 0
5641 }
5642 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5643 cursor.write_bool(self.preserve_source);
5644 cursor.write_bool(self.overwrite_destination);
5645 cursor.skip_30();
5646 cursor.write_composite(&self.source);
5647 cursor.write_composite(&self.destination);
5648 }
5649 }
5650 impl ::emcyphal_encoding::Deserialize for ModifyRequest {
5651 fn deserialize(
5652 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5653 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5654 where
5655 Self: Sized,
5656 {
5657 Ok(ModifyRequest {
5658 preserve_source: { cursor.read_bool() },
5659 overwrite_destination: { cursor.read_bool() },
5660 source: {
5661 cursor.skip_30();
5662 cursor.read_composite()?
5663 },
5664 destination: { cursor.read_composite()? },
5665 })
5666 }
5667 }
5668
5669 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
5674 #[repr(C, packed)]
5675 #[deprecated]
5676 pub struct ModifyResponse {
5677 pub error: crate::uavcan::file::error_1_0::Error,
5683 }
5684 impl ::emcyphal_encoding::DataType for ModifyResponse {
5685 const EXTENT_BYTES: Option<u32> = Some(48);
5687 }
5688 impl ::emcyphal_encoding::Response for ModifyResponse {}
5689 impl ::emcyphal_encoding::BufferType for ModifyResponse {
5690 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
5691 }
5692 impl ModifyResponse {}
5693 impl ::emcyphal_encoding::Serialize for ModifyResponse {
5694 fn size_bits(&self) -> usize {
5695 16
5696 }
5697 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5698 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
5699 }
5700 }
5701 impl ::emcyphal_encoding::Deserialize for ModifyResponse {
5702 fn deserialize(
5703 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5704 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5705 where
5706 Self: Sized,
5707 {
5708 Ok(Self::deserialize_zero_copy(cursor))
5709 }
5710 }
5711 #[test]
5712 fn test_layout() {
5713 assert_eq!(::core::mem::size_of::<ModifyResponse>() * 8, 16);
5714 assert_eq!(::core::mem::offset_of!(ModifyResponse, error) * 8, 0);
5715 }
5716 }
5717 pub mod modify_1_1 {
5718 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5719 pub const SERVICE: ::emcyphal_core::ServiceId =
5720 ::emcyphal_core::ServiceId::from_u16_truncating(407);
5721
5722 #[cfg_attr(
5727 not(doctest),
5728 doc = " Manipulate a remote file system entry. Applies to files, directories, and links alike.\n If the remote entry is a directory, all nested entries will be affected, too.\n\n The server should perform all operations atomically, unless atomicity is not supported by\n the underlying file system.\n\n Atomic copying can be effectively employed by remote nodes before reading or after writing\n the file to minimize the possibility of race conditions.\n For example, before reading a large file from the server, the cilent might opt to create\n a temporary copy of it first, then read the copy, and delete it upon completion. Likewise,\n a similar strategy can be employed for writing, where the file is first written at a\n temporary location, and then moved to its final destination. These approaches, however,\n may lead to creation of dangling temporary files if the client failed to dispose of them\n properly, so that risk should be taken into account.\n\n Move/Copy\n Specify the source path and the destination path.\n If the source does not exist, the operation will fail.\n Set the preserve_source flag to copy rather than move.\n If the destination exists and overwrite_destination is not set, the operation will fail.\n If the target path includes non-existent directories, they will be created (like \"mkdir -p\").\n\n Touch\n Specify the destination path and make the source path empty.\n If the path exists (file/directory/link), its modification time will be updated.\n If the path does not exist, an empty file will be created.\n If the target path includes non-existent directories, they will be created (like \"mkdir -p\").\n Flags are ignored.\n\n Remove\n Specify the source path (file/directory/link) and make the destination path empty.\n Fails if the path does not exist.\n Flags are ignored."
5729 )]
5730 pub struct ModifyRequest {
5731 #[cfg_attr(
5732 not(doctest),
5733 doc = " Do not remove the source. Used to copy instead of moving."
5734 )]
5735 pub preserve_source: bool,
5741 #[cfg_attr(
5742 not(doctest),
5743 doc = " If the destination exists, remove it beforehand."
5744 )]
5745 pub overwrite_destination: bool,
5751 pub source: crate::uavcan::file::path_2_0::Path,
5758 pub destination: crate::uavcan::file::path_2_0::Path,
5764 }
5765 impl ::emcyphal_encoding::DataType for ModifyRequest {
5766 const EXTENT_BYTES: Option<u32> = Some(600);
5768 }
5769 impl ::emcyphal_encoding::Request for ModifyRequest {}
5770 impl ::emcyphal_encoding::BufferType for ModifyRequest {
5771 type Buffer = ::emcyphal_encoding::StaticBuffer<516>;
5772 }
5773 impl ModifyRequest {}
5774 impl ::emcyphal_encoding::Serialize for ModifyRequest {
5775 fn size_bits(&self) -> usize {
5776 1 + 1 + 30 + (self.source).size_bits() + (self.destination).size_bits() + 0
5777 }
5778 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5779 cursor.write_bool(self.preserve_source);
5780 cursor.write_bool(self.overwrite_destination);
5781 cursor.skip_30();
5782 cursor.write_composite(&self.source);
5783 cursor.write_composite(&self.destination);
5784 }
5785 }
5786 impl ::emcyphal_encoding::Deserialize for ModifyRequest {
5787 fn deserialize(
5788 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5789 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5790 where
5791 Self: Sized,
5792 {
5793 Ok(ModifyRequest {
5794 preserve_source: { cursor.read_bool() },
5795 overwrite_destination: { cursor.read_bool() },
5796 source: {
5797 cursor.skip_30();
5798 cursor.read_composite()?
5799 },
5800 destination: { cursor.read_composite()? },
5801 })
5802 }
5803 }
5804
5805 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
5810 #[repr(C, packed)]
5811 pub struct ModifyResponse {
5812 pub error: crate::uavcan::file::error_1_0::Error,
5818 }
5819 impl ::emcyphal_encoding::DataType for ModifyResponse {
5820 const EXTENT_BYTES: Option<u32> = Some(48);
5822 }
5823 impl ::emcyphal_encoding::Response for ModifyResponse {}
5824 impl ::emcyphal_encoding::BufferType for ModifyResponse {
5825 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
5826 }
5827 impl ModifyResponse {}
5828 impl ::emcyphal_encoding::Serialize for ModifyResponse {
5829 fn size_bits(&self) -> usize {
5830 16
5831 }
5832 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5833 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
5834 }
5835 }
5836 impl ::emcyphal_encoding::Deserialize for ModifyResponse {
5837 fn deserialize(
5838 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5839 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5840 where
5841 Self: Sized,
5842 {
5843 Ok(Self::deserialize_zero_copy(cursor))
5844 }
5845 }
5846 #[test]
5847 fn test_layout() {
5848 assert_eq!(::core::mem::size_of::<ModifyResponse>() * 8, 16);
5849 assert_eq!(::core::mem::offset_of!(ModifyResponse, error) * 8, 0);
5850 }
5851 }
5852 #[allow(deprecated)]
5853 #[cfg_attr(not(test), deprecated)]
5854 pub mod path_1_0 {
5855 #[cfg_attr(
5860 not(doctest),
5861 doc = " Nested type.\n A file system path encoded in UTF8. The only valid separator is the forward slash \"/\".\n A single slash (\"/\") refers to the root directory (the location of which is defined by the server).\n Relative references (e.g. \"..\") are not defined and not permitted (although this may change in the future).\n Conventions (not enforced):\n - A path pointing to a file or a link to file should not end with a separator.\n - A path pointing to a directory or to a link to directory should end with a separator.\n\n The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and\n the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance\n of path and no other large data chunks to fit into two CAN FD frames."
5862 )]
5863 #[deprecated]
5864 pub struct Path {
5865 pub path: ::heapless::Vec<u8, 112>,
5871 }
5872 impl ::emcyphal_encoding::DataType for Path {
5873 const EXTENT_BYTES: Option<u32> = None;
5875 }
5876 impl ::emcyphal_encoding::Message for Path {}
5877 impl ::emcyphal_encoding::BufferType for Path {
5878 type Buffer = ::emcyphal_encoding::StaticBuffer<113>;
5879 }
5880 impl Path {
5881 pub const SEPARATOR: u8 = 47;
5882 pub const MAX_LENGTH: u8 = 112;
5883 }
5884 impl ::emcyphal_encoding::Serialize for Path {
5885 fn size_bits(&self) -> usize {
5886 8 + (self.path).len() * 8 + 0
5887 }
5888 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5889 cursor.write_aligned_u8((self.path).len() as u8);
5890 cursor.write_bytes(&(self.path)[..]);
5891 }
5892 }
5893 impl ::emcyphal_encoding::Deserialize for Path {
5894 fn deserialize(
5895 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5896 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5897 where
5898 Self: Sized,
5899 {
5900 Ok(Path {
5901 path: {
5902 let length = cursor.read_u8() as _;
5903 if length <= 112 {
5904 let mut elements = ::heapless::Vec::new();
5905 for _ in 0..length {
5906 let _ = elements.push(cursor.read_u8() as _);
5907 }
5908 elements
5909 } else {
5910 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
5911 }
5912 },
5913 })
5914 }
5915 }
5916 }
5917 pub mod path_2_0 {
5918 #[cfg_attr(
5923 not(doctest),
5924 doc = " Nested type.\n A file system path encoded in UTF8. The only valid separator is the forward slash \"/\".\n A single slash (\"/\") refers to the root directory (the location of which is defined by the server).\n Relative references (e.g. \"..\") are not defined and not permitted (although this may change in the future).\n Conventions (not enforced):\n - A path pointing to a file or a link to file should not end with a separator.\n - A path pointing to a directory or to a link to directory should end with a separator."
5925 )]
5926 pub struct Path {
5927 pub path: ::heapless::Vec<u8, 255>,
5933 }
5934 impl ::emcyphal_encoding::DataType for Path {
5935 const EXTENT_BYTES: Option<u32> = None;
5937 }
5938 impl ::emcyphal_encoding::Message for Path {}
5939 impl ::emcyphal_encoding::BufferType for Path {
5940 type Buffer = ::emcyphal_encoding::StaticBuffer<256>;
5941 }
5942 impl Path {
5943 pub const SEPARATOR: u8 = 47;
5944 pub const MAX_LENGTH: u8 = 255;
5945 }
5946 impl ::emcyphal_encoding::Serialize for Path {
5947 fn size_bits(&self) -> usize {
5948 8 + (self.path).len() * 8 + 0
5949 }
5950 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
5951 cursor.write_aligned_u8((self.path).len() as u8);
5952 cursor.write_bytes(&(self.path)[..]);
5953 }
5954 }
5955 impl ::emcyphal_encoding::Deserialize for Path {
5956 fn deserialize(
5957 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
5958 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
5959 where
5960 Self: Sized,
5961 {
5962 Ok(Path {
5963 path: {
5964 let length = cursor.read_u8() as _;
5965 if length <= 255 {
5966 let mut elements = ::heapless::Vec::new();
5967 for _ in 0..length {
5968 let _ = elements.push(cursor.read_u8() as _);
5969 }
5970 elements
5971 } else {
5972 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
5973 }
5974 },
5975 })
5976 }
5977 }
5978 }
5979 #[allow(deprecated)]
5980 #[cfg_attr(not(test), deprecated)]
5981 pub mod read_1_0 {
5982 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
5983 #[deprecated]
5984 pub const SERVICE: ::emcyphal_core::ServiceId =
5985 ::emcyphal_core::ServiceId::from_u16_truncating(408);
5986
5987 #[cfg_attr(
5992 not(doctest),
5993 doc = " Read file from a remote node.\n\n There are two possible outcomes of a successful call:\n 1. Data array size equals its capacity. This means that the end of the file is not reached yet.\n 2. Data array size is less than its capacity, possibly zero. This means that the end of the file is reached.\n\n Thus, if the client needs to fetch the entire file, it should repeatedly call this service while increasing the\n offset, until a non-full data array is returned.\n\n If the object pointed by 'path' cannot be read (e.g. it is a directory or it does not exist), an appropriate error\n code will be returned, and the data array will be empty.\n\n It is easy to see that this protocol is prone to race conditions because the remote file can be modified\n between read operations which might result in the client obtaining a damaged file. To combat this,\n application designers are recommended to adhere to the following convention. Let every file whose integrity\n is of interest have a hash or a digital signature, which is stored in an adjacent file under the same name\n suffixed with the appropriate extension according to the type of hash or digital signature used.\n For example, let there be file \"image.bin\", integrity of which shall be ensured by the client upon downloading.\n Suppose that the file is hashed using SHA-256, so the appropriate file extension for the hash would be\n \".sha256\". Following this convention, the hash of \"image.bin\" would be stored in \"image.bin.sha256\".\n After downloading the file, the client would read the hash (being small, the hash can be read in a single\n request) and check it against a locally computed value. Some servers may opt to generate such hash files\n automatically as necessary; for example, if such file is requested but it does not exist, the server would\n compute the necessary signature or hash (the type of hash/signature can be deduced from the requested file\n extension) and return it as if the file existed. Obviously, this would be impractical for very large files;\n in that case, hash/signature should be pre-computed and stored in a real file. If this approach is followed,\n implementers are advised to use only SHA-256 for hashing, in order to reduce the number of fielded\n incompatible implementations."
5994 )]
5995 #[deprecated]
5996 pub struct ReadRequest {
5997 pub offset: u64,
6003 pub path: crate::uavcan::file::path_1_0::Path,
6009 }
6010 impl ::emcyphal_encoding::DataType for ReadRequest {
6011 const EXTENT_BYTES: Option<u32> = Some(300);
6013 }
6014 impl ::emcyphal_encoding::Request for ReadRequest {}
6015 impl ::emcyphal_encoding::BufferType for ReadRequest {
6016 type Buffer = ::emcyphal_encoding::StaticBuffer<118>;
6017 }
6018 impl ReadRequest {}
6019 impl ::emcyphal_encoding::Serialize for ReadRequest {
6020 fn size_bits(&self) -> usize {
6021 40 + (self.path).size_bits() + 0
6022 }
6023 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6024 cursor.write_u40(self.offset);
6025 cursor.write_composite(&self.path);
6026 }
6027 }
6028 impl ::emcyphal_encoding::Deserialize for ReadRequest {
6029 fn deserialize(
6030 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6031 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6032 where
6033 Self: Sized,
6034 {
6035 Ok(ReadRequest {
6036 offset: { cursor.read_u40() as _ },
6037 path: { cursor.read_composite()? },
6038 })
6039 }
6040 }
6041
6042 #[deprecated]
6047 pub struct ReadResponse {
6048 pub error: crate::uavcan::file::error_1_0::Error,
6054 pub data: ::heapless::Vec<u8, 256>,
6060 }
6061 impl ::emcyphal_encoding::DataType for ReadResponse {
6062 const EXTENT_BYTES: Option<u32> = Some(300);
6064 }
6065 impl ::emcyphal_encoding::Response for ReadResponse {}
6066 impl ::emcyphal_encoding::BufferType for ReadResponse {
6067 type Buffer = ::emcyphal_encoding::StaticBuffer<260>;
6068 }
6069 impl ReadResponse {}
6070 impl ::emcyphal_encoding::Serialize for ReadResponse {
6071 fn size_bits(&self) -> usize {
6072 16 + 16 + (self.data).len() * 8 + 0
6073 }
6074 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6075 cursor.write_composite(&self.error);
6076 cursor.write_aligned_u16((self.data).len() as u16);
6077 cursor.write_bytes(&(self.data)[..]);
6078 }
6079 }
6080 impl ::emcyphal_encoding::Deserialize for ReadResponse {
6081 fn deserialize(
6082 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6083 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6084 where
6085 Self: Sized,
6086 {
6087 Ok(ReadResponse {
6088 error: { cursor.read_composite()? },
6089 data: {
6090 let length = cursor.read_u16() as _;
6091 if length <= 256 {
6092 let mut elements = ::heapless::Vec::new();
6093 for _ in 0..length {
6094 let _ = elements.push(cursor.read_u8() as _);
6095 }
6096 elements
6097 } else {
6098 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6099 }
6100 },
6101 })
6102 }
6103 }
6104 }
6105 pub mod read_1_1 {
6106 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
6107 pub const SERVICE: ::emcyphal_core::ServiceId =
6108 ::emcyphal_core::ServiceId::from_u16_truncating(408);
6109
6110 #[cfg_attr(
6115 not(doctest),
6116 doc = " Read file from a remote node.\n\n There are two possible outcomes of a successful call:\n 1. Data array size equals its capacity. This means that the end of the file is not reached yet.\n 2. Data array size is less than its capacity, possibly zero. This means that the end of the file is reached.\n\n Thus, if the client needs to fetch the entire file, it should repeatedly call this service while increasing the\n offset, until a non-full data array is returned.\n\n If the object pointed by 'path' cannot be read (e.g. it is a directory or it does not exist), an appropriate error\n code will be returned, and the data array will be empty.\n\n It is easy to see that this protocol is prone to race conditions because the remote file can be modified\n between read operations which might result in the client obtaining a damaged file. To combat this,\n application designers are recommended to adhere to the following convention. Let every file whose integrity\n is of interest have a hash or a digital signature, which is stored in an adjacent file under the same name\n suffixed with the appropriate extension according to the type of hash or digital signature used.\n For example, let there be file \"image.bin\", integrity of which shall be ensured by the client upon downloading.\n Suppose that the file is hashed using SHA-256, so the appropriate file extension for the hash would be\n \".sha256\". Following this convention, the hash of \"image.bin\" would be stored in \"image.bin.sha256\".\n After downloading the file, the client would read the hash (being small, the hash can be read in a single\n request) and check it against a locally computed value. Some servers may opt to generate such hash files\n automatically as necessary; for example, if such file is requested but it does not exist, the server would\n compute the necessary signature or hash (the type of hash/signature can be deduced from the requested file\n extension) and return it as if the file existed. Obviously, this would be impractical for very large files;\n in that case, hash/signature should be pre-computed and stored in a real file. If this approach is followed,\n implementers are advised to use only SHA-256 for hashing, in order to reduce the number of fielded\n incompatible implementations."
6117 )]
6118 pub struct ReadRequest {
6119 pub offset: u64,
6125 pub path: crate::uavcan::file::path_2_0::Path,
6131 }
6132 impl ::emcyphal_encoding::DataType for ReadRequest {
6133 const EXTENT_BYTES: Option<u32> = Some(300);
6135 }
6136 impl ::emcyphal_encoding::Request for ReadRequest {}
6137 impl ::emcyphal_encoding::BufferType for ReadRequest {
6138 type Buffer = ::emcyphal_encoding::StaticBuffer<261>;
6139 }
6140 impl ReadRequest {}
6141 impl ::emcyphal_encoding::Serialize for ReadRequest {
6142 fn size_bits(&self) -> usize {
6143 40 + (self.path).size_bits() + 0
6144 }
6145 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6146 cursor.write_u40(self.offset);
6147 cursor.write_composite(&self.path);
6148 }
6149 }
6150 impl ::emcyphal_encoding::Deserialize for ReadRequest {
6151 fn deserialize(
6152 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6153 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6154 where
6155 Self: Sized,
6156 {
6157 Ok(ReadRequest {
6158 offset: { cursor.read_u40() as _ },
6159 path: { cursor.read_composite()? },
6160 })
6161 }
6162 }
6163
6164 pub struct ReadResponse {
6169 pub error: crate::uavcan::file::error_1_0::Error,
6175 pub data: crate::uavcan::primitive::unstructured_1_0::Unstructured,
6181 }
6182 impl ::emcyphal_encoding::DataType for ReadResponse {
6183 const EXTENT_BYTES: Option<u32> = Some(300);
6185 }
6186 impl ::emcyphal_encoding::Response for ReadResponse {}
6187 impl ::emcyphal_encoding::BufferType for ReadResponse {
6188 type Buffer = ::emcyphal_encoding::StaticBuffer<260>;
6189 }
6190 impl ReadResponse {}
6191 impl ::emcyphal_encoding::Serialize for ReadResponse {
6192 fn size_bits(&self) -> usize {
6193 16 + (self.data).size_bits() + 0
6194 }
6195 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6196 cursor.write_composite(&self.error);
6197 cursor.write_composite(&self.data);
6198 }
6199 }
6200 impl ::emcyphal_encoding::Deserialize for ReadResponse {
6201 fn deserialize(
6202 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6203 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6204 where
6205 Self: Sized,
6206 {
6207 Ok(ReadResponse {
6208 error: { cursor.read_composite()? },
6209 data: { cursor.read_composite()? },
6210 })
6211 }
6212 }
6213 }
6214 #[allow(deprecated)]
6215 #[cfg_attr(not(test), deprecated)]
6216 pub mod write_1_0 {
6217 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
6218 #[deprecated]
6219 pub const SERVICE: ::emcyphal_core::ServiceId =
6220 ::emcyphal_core::ServiceId::from_u16_truncating(409);
6221
6222 #[cfg_attr(
6227 not(doctest),
6228 doc = " Write into a remote file.\n The server shall place the contents of the field 'data' into the file pointed by 'path' at the offset specified by\n the field 'offset'.\n\n When writing a file, the client should repeatedly call this service with data while advancing the offset until the\n file is written completely. When the write sequence is completed, the client shall call the service one last time,\n with the offset set to the size of the file and with the data field empty, which will signal the server that the\n transfer is finished.\n\n When the write operation is complete, the server shall truncate the resulting file past the specified offset."
6229 )]
6230 #[deprecated]
6231 pub struct WriteRequest {
6232 pub offset: u64,
6238 pub path: crate::uavcan::file::path_1_0::Path,
6244 #[cfg_attr(
6245 not(doctest),
6246 doc = " 192 = 128 + 64; the write protocol permits usage of smaller chunks."
6247 )]
6248 pub data: ::heapless::Vec<u8, 192>,
6254 }
6255 impl ::emcyphal_encoding::DataType for WriteRequest {
6256 const EXTENT_BYTES: Option<u32> = Some(600);
6258 }
6259 impl ::emcyphal_encoding::Request for WriteRequest {}
6260 impl ::emcyphal_encoding::BufferType for WriteRequest {
6261 type Buffer = ::emcyphal_encoding::StaticBuffer<311>;
6262 }
6263 impl WriteRequest {}
6264 impl ::emcyphal_encoding::Serialize for WriteRequest {
6265 fn size_bits(&self) -> usize {
6266 40 + (self.path).size_bits() + 8 + (self.data).len() * 8 + 0
6267 }
6268 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6269 cursor.write_u40(self.offset);
6270 cursor.write_composite(&self.path);
6271 cursor.write_aligned_u8((self.data).len() as u8);
6272 cursor.write_bytes(&(self.data)[..]);
6273 }
6274 }
6275 impl ::emcyphal_encoding::Deserialize for WriteRequest {
6276 fn deserialize(
6277 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6278 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6279 where
6280 Self: Sized,
6281 {
6282 Ok(WriteRequest {
6283 offset: { cursor.read_u40() as _ },
6284 path: { cursor.read_composite()? },
6285 data: {
6286 let length = cursor.read_u8() as _;
6287 if length <= 192 {
6288 let mut elements = ::heapless::Vec::new();
6289 for _ in 0..length {
6290 let _ = elements.push(cursor.read_u8() as _);
6291 }
6292 elements
6293 } else {
6294 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6295 }
6296 },
6297 })
6298 }
6299 }
6300
6301 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
6306 #[repr(C, packed)]
6307 #[deprecated]
6308 pub struct WriteResponse {
6309 pub error: crate::uavcan::file::error_1_0::Error,
6315 }
6316 impl ::emcyphal_encoding::DataType for WriteResponse {
6317 const EXTENT_BYTES: Option<u32> = Some(48);
6319 }
6320 impl ::emcyphal_encoding::Response for WriteResponse {}
6321 impl ::emcyphal_encoding::BufferType for WriteResponse {
6322 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
6323 }
6324 impl WriteResponse {}
6325 impl ::emcyphal_encoding::Serialize for WriteResponse {
6326 fn size_bits(&self) -> usize {
6327 16
6328 }
6329 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6330 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
6331 }
6332 }
6333 impl ::emcyphal_encoding::Deserialize for WriteResponse {
6334 fn deserialize(
6335 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6336 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6337 where
6338 Self: Sized,
6339 {
6340 Ok(Self::deserialize_zero_copy(cursor))
6341 }
6342 }
6343 #[test]
6344 fn test_layout() {
6345 assert_eq!(::core::mem::size_of::<WriteResponse>() * 8, 16);
6346 assert_eq!(::core::mem::offset_of!(WriteResponse, error) * 8, 0);
6347 }
6348 }
6349 pub mod write_1_1 {
6350 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
6351 pub const SERVICE: ::emcyphal_core::ServiceId =
6352 ::emcyphal_core::ServiceId::from_u16_truncating(409);
6353
6354 #[cfg_attr(
6359 not(doctest),
6360 doc = " Write into a remote file.\n The server shall place the contents of the field 'data' into the file pointed by 'path' at the offset specified by\n the field 'offset'.\n\n When writing a file, the client should repeatedly call this service with data while advancing the offset until the\n file is written completely. When the write sequence is completed, the client shall call the service one last time,\n with the offset set to the size of the file and with the data field empty, which will signal the server that the\n transfer is finished.\n\n When the write operation is complete, the server shall truncate the resulting file past the specified offset."
6361 )]
6362 pub struct WriteRequest {
6363 pub offset: u64,
6369 pub path: crate::uavcan::file::path_2_0::Path,
6375 pub data: crate::uavcan::primitive::unstructured_1_0::Unstructured,
6381 }
6382 impl ::emcyphal_encoding::DataType for WriteRequest {
6383 const EXTENT_BYTES: Option<u32> = Some(600);
6385 }
6386 impl ::emcyphal_encoding::Request for WriteRequest {}
6387 impl ::emcyphal_encoding::BufferType for WriteRequest {
6388 type Buffer = ::emcyphal_encoding::StaticBuffer<519>;
6389 }
6390 impl WriteRequest {}
6391 impl ::emcyphal_encoding::Serialize for WriteRequest {
6392 fn size_bits(&self) -> usize {
6393 40 + (self.path).size_bits() + (self.data).size_bits() + 0
6394 }
6395 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6396 cursor.write_u40(self.offset);
6397 cursor.write_composite(&self.path);
6398 cursor.write_composite(&self.data);
6399 }
6400 }
6401 impl ::emcyphal_encoding::Deserialize for WriteRequest {
6402 fn deserialize(
6403 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6404 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6405 where
6406 Self: Sized,
6407 {
6408 Ok(WriteRequest {
6409 offset: { cursor.read_u40() as _ },
6410 path: { cursor.read_composite()? },
6411 data: { cursor.read_composite()? },
6412 })
6413 }
6414 }
6415
6416 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
6421 #[repr(C, packed)]
6422 pub struct WriteResponse {
6423 pub error: crate::uavcan::file::error_1_0::Error,
6429 }
6430 impl ::emcyphal_encoding::DataType for WriteResponse {
6431 const EXTENT_BYTES: Option<u32> = Some(48);
6433 }
6434 impl ::emcyphal_encoding::Response for WriteResponse {}
6435 impl ::emcyphal_encoding::BufferType for WriteResponse {
6436 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
6437 }
6438 impl WriteResponse {}
6439 impl ::emcyphal_encoding::Serialize for WriteResponse {
6440 fn size_bits(&self) -> usize {
6441 16
6442 }
6443 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6444 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
6445 }
6446 }
6447 impl ::emcyphal_encoding::Deserialize for WriteResponse {
6448 fn deserialize(
6449 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6450 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6451 where
6452 Self: Sized,
6453 {
6454 Ok(Self::deserialize_zero_copy(cursor))
6455 }
6456 }
6457 #[test]
6458 fn test_layout() {
6459 assert_eq!(::core::mem::size_of::<WriteResponse>() * 8, 16);
6460 assert_eq!(::core::mem::offset_of!(WriteResponse, error) * 8, 0);
6461 }
6462 }
6463 }
6464 pub mod internet {
6465 pub mod udp {
6466 #[allow(deprecated)]
6467 #[cfg_attr(not(test), deprecated)]
6468 pub mod handle_incoming_packet_0_1 {
6469 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
6470 #[deprecated]
6471 pub const SERVICE: ::emcyphal_core::ServiceId =
6472 ::emcyphal_core::ServiceId::from_u16_truncating(500);
6473
6474 #[cfg_attr(
6479 not(doctest),
6480 doc = " This message carries UDP packets sent from a remote host on the Internet or a LAN to a node on the local Cyphal bus.\n Please refer to the definition of the message type OutgoingPacket for a general overview of the packet forwarding\n logic.\n\n This data type has been made a service type rather than a message type in order to make its transfers addressable,\n allowing nodes to employ hardware acceptance filters for filtering out forwarded datagrams that are not addressed\n to them. Additionally, requiring the destination nodes to always respond upon reception of the forwarded datagram\n opens interesting opportunities for future extensions of the forwarding protocol. If the service invocation times\n out, the modem node is permitted to remove the corresponding entry from the NAT table immediately, not waiting\n for its TTL to expire.\n\n It should be noted that this data type definition intentionally leaves out the source address. This is done in\n order to simplify the implementation, reduce the bus traffic overhead, and because the nature of the\n communication patterns proposed by this set of messages does not provide a valid way to implement server hosts\n on the local Cyphal bus. It is assumed that local nodes can be only clients, and therefore, they will be able to\n determine the address of the sender simply by mapping the field session_id to their internally maintained states.\n Furthermore, it is uncertain what is the optimal way of representing the source address for\n client nodes: it is assumed that the local nodes will mostly use DNS names rather than IP addresses, so if there\n was a source address field, modem nodes would have to perform reverse mapping from the IP address they received\n the datagram from to the corresponding DNS name that was used by the local node with the outgoing message. This\n approach creates a number of troubling corner cases and adds a fair amount of hidden complexities to the\n implementation of modem nodes.\n\n It is recommended to perform service invocations at the same transfer priority level as was used for broadcasting\n the latest matching message of type OutgoingPacket. However, meeting this recommendation would require the modem\n node to implement additional logic, which may be undesirable. Therefore, implementers are free to deviate from\n this recommendation and resort to a fixed priority level instead. In the case of a fixed priority level, it is\n advised to use the lowest transfer priority level."
6481 )]
6482 #[deprecated]
6483 pub struct HandleIncomingPacketRequest {
6484 #[cfg_attr(
6485 not(doctest),
6486 doc = " This field shall contain the same value that was used by the local node when sending the corresponding outgoing\n packet using the message type OutgoingPacket. This value will be used by the local node to match the response\n with its local context."
6487 )]
6488 pub session_id: u16,
6494 #[cfg_attr(
6495 not(doctest),
6496 doc = " Effective payload. This data will be forwarded from the remote host verbatim.\n UDP packets that contain more than 508 bytes of payload may be dropped by some types of\n communication equipment. Refer to RFC 791 and 2460 for an in-depth review.\n Cyphal further limits the maximum packet size to reduce the memory and traffic burden on the nodes.\n Datagrams that exceed the capacity of this field should be discarded by the modem node."
6497 )]
6498 pub payload: ::heapless::Vec<u8, 309>,
6504 }
6505 impl ::emcyphal_encoding::DataType for HandleIncomingPacketRequest {
6506 const EXTENT_BYTES: Option<u32> = Some(600);
6508 }
6509 impl ::emcyphal_encoding::Request for HandleIncomingPacketRequest {}
6510 impl ::emcyphal_encoding::BufferType for HandleIncomingPacketRequest {
6511 type Buffer = ::emcyphal_encoding::StaticBuffer<313>;
6512 }
6513 impl HandleIncomingPacketRequest {}
6514 impl ::emcyphal_encoding::Serialize for HandleIncomingPacketRequest {
6515 fn size_bits(&self) -> usize {
6516 16 + 16 + (self.payload).len() * 8 + 0
6517 }
6518 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6519 cursor.write_aligned_u16(self.session_id);
6520 cursor.write_aligned_u16((self.payload).len() as u16);
6521 cursor.write_bytes(&(self.payload)[..]);
6522 }
6523 }
6524 impl ::emcyphal_encoding::Deserialize for HandleIncomingPacketRequest {
6525 fn deserialize(
6526 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6527 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6528 where
6529 Self: Sized,
6530 {
6531 Ok(HandleIncomingPacketRequest {
6532 session_id: { cursor.read_u16() as _ },
6533 payload: {
6534 let length = cursor.read_u16() as _;
6535 if length <= 309 {
6536 let mut elements = ::heapless::Vec::new();
6537 for _ in 0..length {
6538 let _ = elements.push(cursor.read_u8() as _);
6539 }
6540 elements
6541 } else {
6542 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6543 }
6544 },
6545 })
6546 }
6547 }
6548
6549 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
6554 #[repr(C, packed)]
6555 #[deprecated]
6556 pub struct HandleIncomingPacketResponse {}
6557 impl ::emcyphal_encoding::DataType for HandleIncomingPacketResponse {
6558 const EXTENT_BYTES: Option<u32> = Some(63);
6560 }
6561 impl ::emcyphal_encoding::Response for HandleIncomingPacketResponse {}
6562 impl ::emcyphal_encoding::BufferType for HandleIncomingPacketResponse {
6563 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
6564 }
6565 impl HandleIncomingPacketResponse {}
6566 impl ::emcyphal_encoding::Serialize for HandleIncomingPacketResponse {
6567 fn size_bits(&self) -> usize {
6568 0
6569 }
6570 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6571 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
6572 }
6573 }
6574 impl ::emcyphal_encoding::Deserialize for HandleIncomingPacketResponse {
6575 fn deserialize(
6576 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6577 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6578 where
6579 Self: Sized,
6580 {
6581 Ok(Self::deserialize_zero_copy(cursor))
6582 }
6583 }
6584 #[test]
6585 fn test_layout() {
6586 assert_eq!(
6587 ::core::mem::size_of::<HandleIncomingPacketResponse>() * 8,
6588 0
6589 );
6590 }
6591 }
6592 pub mod handle_incoming_packet_0_2 {
6593 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
6594 pub const SERVICE: ::emcyphal_core::ServiceId =
6595 ::emcyphal_core::ServiceId::from_u16_truncating(500);
6596
6597 #[cfg_attr(
6602 not(doctest),
6603 doc = " This message carries UDP packets sent from a remote host on the Internet or a LAN to a node on the local Cyphal bus.\n Please refer to the definition of the message type OutgoingPacket for a general overview of the packet forwarding\n logic.\n\n This data type has been made a service type rather than a message type in order to make its transfers addressable,\n allowing nodes to employ hardware acceptance filters for filtering out forwarded datagrams that are not addressed\n to them. Additionally, requiring the destination nodes to always respond upon reception of the forwarded datagram\n opens interesting opportunities for future extensions of the forwarding protocol. If the service invocation times\n out, the modem node is permitted to remove the corresponding entry from the NAT table immediately, not waiting\n for its TTL to expire.\n\n It should be noted that this data type definition intentionally leaves out the source address. This is done in\n order to simplify the implementation, reduce the bus traffic overhead, and because the nature of the\n communication patterns proposed by this set of messages does not provide a valid way to implement server hosts\n on the local Cyphal bus. It is assumed that local nodes can be only clients, and therefore, they will be able to\n determine the address of the sender simply by mapping the field session_id to their internally maintained states.\n Furthermore, it is uncertain what is the optimal way of representing the source address for\n client nodes: it is assumed that the local nodes will mostly use DNS names rather than IP addresses, so if there\n was a source address field, modem nodes would have to perform reverse mapping from the IP address they received\n the datagram from to the corresponding DNS name that was used by the local node with the outgoing message. This\n approach creates a number of troubling corner cases and adds a fair amount of hidden complexities to the\n implementation of modem nodes.\n\n It is recommended to perform service invocations at the same transfer priority level as was used for broadcasting\n the latest matching message of type OutgoingPacket. However, meeting this recommendation would require the modem\n node to implement additional logic, which may be undesirable. Therefore, implementers are free to deviate from\n this recommendation and resort to a fixed priority level instead. In the case of a fixed priority level, it is\n advised to use the lowest transfer priority level."
6604 )]
6605 pub struct HandleIncomingPacketRequest {
6606 #[cfg_attr(
6607 not(doctest),
6608 doc = " This field shall contain the same value that was used by the local node when sending the corresponding outgoing\n packet using the message type OutgoingPacket. This value will be used by the local node to match the response\n with its local context."
6609 )]
6610 pub session_id: u16,
6616 #[cfg_attr(
6617 not(doctest),
6618 doc = " Effective payload. This data will be forwarded from the remote host verbatim.\n UDP packets that contain more than 508 bytes of payload may be dropped by some types of\n communication equipment. Refer to RFC 791 and 2460 for an in-depth review.\n Datagrams that exceed the capacity of this field should be discarded by the modem node."
6619 )]
6620 pub payload: ::heapless::Vec<u8, 508>,
6626 }
6627 impl ::emcyphal_encoding::DataType for HandleIncomingPacketRequest {
6628 const EXTENT_BYTES: Option<u32> = Some(600);
6630 }
6631 impl ::emcyphal_encoding::Request for HandleIncomingPacketRequest {}
6632 impl ::emcyphal_encoding::BufferType for HandleIncomingPacketRequest {
6633 type Buffer = ::emcyphal_encoding::StaticBuffer<512>;
6634 }
6635 impl HandleIncomingPacketRequest {}
6636 impl ::emcyphal_encoding::Serialize for HandleIncomingPacketRequest {
6637 fn size_bits(&self) -> usize {
6638 16 + 16 + (self.payload).len() * 8 + 0
6639 }
6640 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6641 cursor.write_aligned_u16(self.session_id);
6642 cursor.write_aligned_u16((self.payload).len() as u16);
6643 cursor.write_bytes(&(self.payload)[..]);
6644 }
6645 }
6646 impl ::emcyphal_encoding::Deserialize for HandleIncomingPacketRequest {
6647 fn deserialize(
6648 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6649 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6650 where
6651 Self: Sized,
6652 {
6653 Ok(HandleIncomingPacketRequest {
6654 session_id: { cursor.read_u16() as _ },
6655 payload: {
6656 let length = cursor.read_u16() as _;
6657 if length <= 508 {
6658 let mut elements = ::heapless::Vec::new();
6659 for _ in 0..length {
6660 let _ = elements.push(cursor.read_u8() as _);
6661 }
6662 elements
6663 } else {
6664 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6665 }
6666 },
6667 })
6668 }
6669 }
6670
6671 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
6676 #[repr(C, packed)]
6677 pub struct HandleIncomingPacketResponse {}
6678 impl ::emcyphal_encoding::DataType for HandleIncomingPacketResponse {
6679 const EXTENT_BYTES: Option<u32> = Some(63);
6681 }
6682 impl ::emcyphal_encoding::Response for HandleIncomingPacketResponse {}
6683 impl ::emcyphal_encoding::BufferType for HandleIncomingPacketResponse {
6684 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
6685 }
6686 impl HandleIncomingPacketResponse {}
6687 impl ::emcyphal_encoding::Serialize for HandleIncomingPacketResponse {
6688 fn size_bits(&self) -> usize {
6689 0
6690 }
6691 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6692 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
6693 }
6694 }
6695 impl ::emcyphal_encoding::Deserialize for HandleIncomingPacketResponse {
6696 fn deserialize(
6697 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6698 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6699 where
6700 Self: Sized,
6701 {
6702 Ok(Self::deserialize_zero_copy(cursor))
6703 }
6704 }
6705 #[test]
6706 fn test_layout() {
6707 assert_eq!(
6708 ::core::mem::size_of::<HandleIncomingPacketResponse>() * 8,
6709 0
6710 );
6711 }
6712 }
6713 #[allow(deprecated)]
6714 #[cfg_attr(not(test), deprecated)]
6715 pub mod outgoing_packet_0_1 {
6716 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
6717 #[deprecated]
6718 pub const SUBJECT: ::emcyphal_core::SubjectId =
6719 ::emcyphal_core::SubjectId::from_u16_truncating(8174);
6720
6721 #[cfg_attr(
6726 not(doctest),
6727 doc = " This message carries UDP packets from a node on the local bus to a remote host on the Internet or a LAN.\n\n Any node can broadcast a message of this type.\n\n All nodes that are capable of communication with the Internet or a LAN should subscribe to messages\n of this type and forward the payload to the indicated host and port using exactly one UDP datagram\n per message (i.e. additional fragmentation is to be avoided). Such nodes will be referred to as\n \"modem nodes\".\n\n It is expected that some systems will have more than one modem node available.\n Each modem node is supposed to forward every message it sees, which will naturally create\n some degree of modular redundancy and fault tolerance. The remote host should therefore be able to\n properly handle possibly duplicated messages from different source addresses, in addition to\n possible duplications introduced by the UDP/IP protocol itself. There are at least two obvious\n strategies that can be employed by the remote host:\n\n - Accept only the first message, ignore duplicates. This approach requires that the UDP stream\n should contain some metadata necessary for the remote host to determine the source and ordering\n of each received datum. This approach works best for periodic data, such as telemetry, where\n the sender does not expect any responses.\n\n - Process all messages, including duplicates. This approach assumes that the remote host acts\n as a server, processing all received requests and providing responses to each. This arrangement\n implies that the client may receive duplicated responses. It is therefore the client's\n responsibility to resolve the possible ambiguity. An obvious solution is to accept the first\n arrived response and ignore the later ones.\n\n Applications are free to choose whatever redundancy management strategy works best for them.\n\n If the source node expects that the remote host will send some data back, it shall explicitly notify\n the modem nodes about this, so that they could prepare to perform reverse forwarding when the\n expected data arrives from the remote host. The technique of reverse forwarding is known in\n networking as IP Masquerading, or (in general) Network Address Translation (NAT). The notification\n is performed by means of setting one of the corresponding flags defined below.\n\n In order to be able to match datagrams received from remote hosts and the local nodes they should\n be forwarded to, modem nodes are required to keep certain metadata about outgoing datagrams. Such\n metadata is stored in a data structure referred to as \"NAT table\", where every entry would normally\n contain at least the following fields:\n - The local UDP port number that was used to send the outgoing datagram from.\n Per RFC 4787, the port number is chosen by the modem node automatically.\n - The node-ID of the local node that has sent the outgoing datagram.\n - Value of the field session_id defined below.\n - Possibly some other data, depending on the implementation.\n\n The modem nodes are required to keep each NAT table entry for at least NAT_ENTRY_MIN_TTL seconds\n since the last reverse forwarding action was performed. Should the memory resources of the modem node\n be exhausted, it is allowed to remove old NAT entries earlier, following the policy of least recent use.\n\n Having received a UDP packet from a remote host, the modem node would check the NAT table in order\n to determine where on the Cyphal bus the received data should be forwarded to. If the NAT table\n contains no matches, the received data should be silently dropped. If a match is found, the\n modem node will forward the data to the recipient node using the service HandleIncomingPacket.\n If the service invocation times out, the modem node is permitted to remove the corresponding entry from\n the NAT table immediately (but it is not required). This will ensure that the modem nodes will not be\n tasked with translations for client nodes that are no longer online or are unreachable.\n Additionally, client nodes will be able to hint the modem nodes to remove translation entries they no\n longer need by simply refusing to respond to the corresponding service invocation. Please refer to\n the definition of that service data type for a more in-depth review of the reverse forwarding process.\n\n Modem nodes can also perform traffic shaping, if needed, by means of delaying or dropping UDP\n datagrams that exceed the quota.\n\n To summarize, a typical data exchange occurrence should amount to the following actions:\n\n - A local Cyphal node broadcasts a message of type OutgoingPacket with the payload it needs\n to forward. If the node expects the remote host to send any data back, it sets the masquerading flag.\n\n - Every modem node on the bus receives the message and performs the following actions:\n\n - The domain name is resolved, unless the destination address provided in the message\n is already an IP address, in which case this step should be skipped.\n\n - The domain name to IP address mapping is added to the local DNS cache, although this\n part is entirely implementation defined and is not required.\n\n - The masquerading flag is checked. If it is set, a new entry is added to the NAT table.\n If such entry already existed, its expiration timeout is reset. If no such entry existed\n and a new one cannot be added because of memory limitations, the least recently used\n (i.e. oldest) entry of the NAT table is replaced with the new one.\n\n - The payload is forwarded to the determined IP address.\n\n - At this point, direct forwarding is complete. Should any of the modem nodes receive an incoming\n packet, they would attempt to perform a reverse forwarding according to the above provided algorithm.\n\n It is recommended to use the lowest transport priority level when broadcasting messages of this type,\n in order to avoid interference with a real-time traffic on the bus. Usage of higher priority levels is\n unlikely to be practical because the latency and throughput limitations introduced by the on-board radio\n communication equipment are likely to vastly exceed those of the local CAN bus."
6728 )]
6729 #[deprecated]
6730 pub struct OutgoingPacket {
6731 #[cfg_attr(
6732 not(doctest),
6733 doc = " This field is set to an arbitrary value by the transmitting node in order to be able to match the response\n with the locally kept context. The function of this field is virtually identical to that of UDP/IP port\n numbers. This value can be set to zero safely if the sending node does not have multiple contexts to\n distinguish between."
6734 )]
6735 pub session_id: u16,
6741 #[cfg_attr(not(doctest), doc = " UDP destination port number.")]
6742 pub destination_port: u16,
6748 #[cfg_attr(
6749 not(doctest),
6750 doc = " Domain name or IP address where the payload should be forwarded to.\n Note that broadcast addresses are allowed here, for example, 255.255.255.255.\n Broadcasting with masquerading enabled works the same way as unicasting with masquerading enabled: the modem\n node should take care to channel all traffic arriving at the opened port from any source to the node that\n requested masquerading.\n The full domain name length may not exceed 253 octets, according to the DNS specification.\n Cyphal imposes a stricter length limit in order to reduce the memory and traffic burden on the bus: 45 characters.\n 45 characters is the amount of space that is required to represent the longest possible form of an IPv6 address\n (an IPv4-mapped IPv6 address). Examples:\n \"forum.opencyphal.org\" - domain name\n \"192.168.1.1\" - IPv4 address\n \"2001:0db8:85a3:0000:0000:8a2e:0370:7334\" - IPv6 address, full form\n \"2001:db8:85a3::8a2e:370:7334\" - IPv6 address, same as above, short form (preferred)\n \"ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190\" - IPv4-mapped IPv6, full form (length limit, 45 characters)"
6751 )]
6752 pub destination_address: ::heapless::Vec<u8, 45>,
6758 #[cfg_attr(
6759 not(doctest),
6760 doc = " Expect data back (i.e., instruct the modem to use the NAT table)."
6761 )]
6762 pub use_masquerading: bool,
6768 #[cfg_attr(
6769 not(doctest),
6770 doc = " Use Datagram Transport Layer Security. Drop the packet if DTLS is not supported.\n Option flags."
6771 )]
6772 pub use_dtls: bool,
6778 #[cfg_attr(
6780 not(doctest),
6781 doc = " Effective payload. This data will be forwarded to the remote host verbatim.\n UDP packets that contain more than 508 bytes of payload may be dropped by some types of\n communication equipment. Refer to RFC 791 and 2460 for an in-depth review.\n Cyphal further limits the maximum packet size to reduce the memory and traffic burden on the nodes."
6782 )]
6783 pub payload: ::heapless::Vec<u8, 260>,
6789 }
6790 impl ::emcyphal_encoding::DataType for OutgoingPacket {
6791 const EXTENT_BYTES: Option<u32> = Some(600);
6793 }
6794 impl ::emcyphal_encoding::Message for OutgoingPacket {}
6795 impl ::emcyphal_encoding::BufferType for OutgoingPacket {
6796 type Buffer = ::emcyphal_encoding::StaticBuffer<313>;
6797 }
6798 impl OutgoingPacket {
6799 #[cfg_attr(
6800 not(doctest),
6801 doc = " [second]\n Modem nodes are required to keep the NAT table entries alive for at least this amount of time, unless the\n table is overflowed, in which case they are allowed to remove least recently used entries in favor of\n newer ones. Modem nodes are required to be able to accommodate at least 100 entries in the NAT table."
6802 )]
6803 pub const NAT_ENTRY_MIN_TTL: u32 = 86400;
6804 }
6805 impl ::emcyphal_encoding::Serialize for OutgoingPacket {
6806 fn size_bits(&self) -> usize {
6807 16 + 16
6808 + 8
6809 + (self.destination_address).len() * 8
6810 + 1
6811 + 1
6812 + 6
6813 + 16
6814 + (self.payload).len() * 8
6815 + 0
6816 }
6817 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6818 cursor.write_aligned_u16(self.session_id);
6819 cursor.write_aligned_u16(self.destination_port);
6820 cursor.write_aligned_u8((self.destination_address).len() as u8);
6821 cursor.write_bytes(&(self.destination_address)[..]);
6822 cursor.write_bool(self.use_masquerading);
6823 cursor.write_bool(self.use_dtls);
6824 cursor.skip_6();
6825 cursor.write_aligned_u16((self.payload).len() as u16);
6826 cursor.write_bytes(&(self.payload)[..]);
6827 }
6828 }
6829 impl ::emcyphal_encoding::Deserialize for OutgoingPacket {
6830 fn deserialize(
6831 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6832 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6833 where
6834 Self: Sized,
6835 {
6836 Ok(OutgoingPacket {
6837 session_id: { cursor.read_u16() as _ },
6838 destination_port: { cursor.read_u16() as _ },
6839 destination_address: {
6840 let length = cursor.read_u8() as _;
6841 if length <= 45 {
6842 let mut elements = ::heapless::Vec::new();
6843 for _ in 0..length {
6844 let _ = elements.push(cursor.read_u8() as _);
6845 }
6846 elements
6847 } else {
6848 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6849 }
6850 },
6851 use_masquerading: { cursor.read_bool() },
6852 use_dtls: { cursor.read_bool() },
6853 payload: {
6854 cursor.skip_6();
6855 let length = cursor.read_u16() as _;
6856 if length <= 260 {
6857 let mut elements = ::heapless::Vec::new();
6858 for _ in 0..length {
6859 let _ = elements.push(cursor.read_u8() as _);
6860 }
6861 elements
6862 } else {
6863 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
6864 }
6865 },
6866 })
6867 }
6868 }
6869 }
6870 pub mod outgoing_packet_0_2 {
6871 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
6872 pub const SUBJECT: ::emcyphal_core::SubjectId =
6873 ::emcyphal_core::SubjectId::from_u16_truncating(8174);
6874
6875 #[cfg_attr(
6880 not(doctest),
6881 doc = " This message carries UDP packets from a node on the local bus to a remote host on the Internet or a LAN.\n\n Any node can broadcast a message of this type.\n\n All nodes that are capable of communication with the Internet or a LAN should subscribe to messages\n of this type and forward the payload to the indicated host and port using exactly one UDP datagram\n per message (i.e. additional fragmentation is to be avoided). Such nodes will be referred to as\n \"modem nodes\".\n\n It is expected that some systems will have more than one modem node available.\n Each modem node is supposed to forward every message it sees, which will naturally create\n some degree of modular redundancy and fault tolerance. The remote host should therefore be able to\n properly handle possibly duplicated messages from different source addresses, in addition to\n possible duplications introduced by the UDP/IP protocol itself. There are at least two obvious\n strategies that can be employed by the remote host:\n\n - Accept only the first message, ignore duplicates. This approach requires that the UDP stream\n should contain some metadata necessary for the remote host to determine the source and ordering\n of each received datum. This approach works best for periodic data, such as telemetry, where\n the sender does not expect any responses.\n\n - Process all messages, including duplicates. This approach assumes that the remote host acts\n as a server, processing all received requests and providing responses to each. This arrangement\n implies that the client may receive duplicated responses. It is therefore the client's\n responsibility to resolve the possible ambiguity. An obvious solution is to accept the first\n arrived response and ignore the later ones.\n\n Applications are free to choose whatever redundancy management strategy works best for them.\n\n If the source node expects that the remote host will send some data back, it shall explicitly notify\n the modem nodes about this, so that they could prepare to perform reverse forwarding when the\n expected data arrives from the remote host. The technique of reverse forwarding is known in\n networking as IP Masquerading, or (in general) Network Address Translation (NAT). The notification\n is performed by means of setting one of the corresponding flags defined below.\n\n In order to be able to match datagrams received from remote hosts and the local nodes they should\n be forwarded to, modem nodes are required to keep certain metadata about outgoing datagrams. Such\n metadata is stored in a data structure referred to as \"NAT table\", where every entry would normally\n contain at least the following fields:\n - The local UDP port number that was used to send the outgoing datagram from.\n Per RFC 4787, the port number is chosen by the modem node automatically.\n - The node-ID of the local node that has sent the outgoing datagram.\n - Value of the field session_id defined below.\n - Possibly some other data, depending on the implementation.\n\n The modem nodes are required to keep each NAT table entry for at least NAT_ENTRY_MIN_TTL seconds\n since the last reverse forwarding action was performed. Should the memory resources of the modem node\n be exhausted, it is allowed to remove old NAT entries earlier, following the policy of least recent use.\n\n Having received a UDP packet from a remote host, the modem node would check the NAT table in order\n to determine where on the Cyphal bus the received data should be forwarded to. If the NAT table\n contains no matches, the received data should be silently dropped. If a match is found, the\n modem node will forward the data to the recipient node using the service HandleIncomingPacket.\n If the service invocation times out, the modem node is permitted to remove the corresponding entry from\n the NAT table immediately (but it is not required). This will ensure that the modem nodes will not be\n tasked with translations for client nodes that are no longer online or are unreachable.\n Additionally, client nodes will be able to hint the modem nodes to remove translation entries they no\n longer need by simply refusing to respond to the corresponding service invocation. Please refer to\n the definition of that service data type for a more in-depth review of the reverse forwarding process.\n\n Modem nodes can also perform traffic shaping, if needed, by means of delaying or dropping UDP\n datagrams that exceed the quota.\n\n To summarize, a typical data exchange occurrence should amount to the following actions:\n\n - A local Cyphal node broadcasts a message of type OutgoingPacket with the payload it needs\n to forward. If the node expects the remote host to send any data back, it sets the masquerading flag.\n\n - Every modem node on the bus receives the message and performs the following actions:\n\n - The domain name is resolved, unless the destination address provided in the message\n is already an IP address, in which case this step should be skipped.\n\n - The domain name to IP address mapping is added to the local DNS cache, although this\n part is entirely implementation defined and is not required.\n\n - The masquerading flag is checked. If it is set, a new entry is added to the NAT table.\n If such entry already existed, its expiration timeout is reset. If no such entry existed\n and a new one cannot be added because of memory limitations, the least recently used\n (i.e. oldest) entry of the NAT table is replaced with the new one.\n\n - The payload is forwarded to the determined IP address.\n\n - At this point, direct forwarding is complete. Should any of the modem nodes receive an incoming\n packet, they would attempt to perform a reverse forwarding according to the above provided algorithm.\n\n It is recommended to use the lowest transport priority level when broadcasting messages of this type,\n in order to avoid interference with a real-time traffic on the bus. Usage of higher priority levels is\n unlikely to be practical because the latency and throughput limitations introduced by the on-board radio\n communication equipment are likely to vastly exceed those of the local CAN bus."
6882 )]
6883 pub struct OutgoingPacket {
6884 #[cfg_attr(
6885 not(doctest),
6886 doc = " This field is set to an arbitrary value by the transmitting node in order to be able to match the response\n with the locally kept context. The function of this field is virtually identical to that of UDP/IP port\n numbers. This value can be set to zero safely if the sending node does not have multiple contexts to\n distinguish between."
6887 )]
6888 pub session_id: u16,
6894 #[cfg_attr(not(doctest), doc = " UDP destination port number.")]
6895 pub destination_port: u16,
6901 #[cfg_attr(
6902 not(doctest),
6903 doc = " Domain name or IP address where the payload should be forwarded to.\n Note that broadcast addresses are allowed here, for example, 255.255.255.255.\n Broadcasting with masquerading enabled works the same way as unicasting with masquerading enabled: the modem\n node should take care to channel all traffic arriving at the opened port from any source to the node that\n requested masquerading.\n The full domain name length may not exceed 253 octets, according to the DNS specification.\n Cyphal imposes a stricter length limit in order to reduce the memory and traffic burden on the bus: 45 characters.\n 45 characters is the amount of space that is required to represent the longest possible form of an IPv6 address\n (an IPv4-mapped IPv6 address). Examples:\n \"forum.opencyphal.org\" - domain name\n \"192.168.1.1\" - IPv4 address\n \"2001:0db8:85a3:0000:0000:8a2e:0370:7334\" - IPv6 address, full form\n \"2001:db8:85a3::8a2e:370:7334\" - IPv6 address, same as above, short form (preferred)\n \"ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190\" - IPv4-mapped IPv6, full form (length limit, 45 characters)"
6904 )]
6905 pub destination_address: ::heapless::Vec<u8, 45>,
6911 #[cfg_attr(
6912 not(doctest),
6913 doc = " Expect data back (i.e., instruct the modem to use the NAT table)."
6914 )]
6915 pub use_masquerading: bool,
6921 #[cfg_attr(
6922 not(doctest),
6923 doc = " Use Datagram Transport Layer Security. Drop the packet if DTLS is not supported.\n Option flags."
6924 )]
6925 pub use_dtls: bool,
6931 #[cfg_attr(
6933 not(doctest),
6934 doc = " Effective payload. This data will be forwarded to the remote host verbatim.\n UDP packets that contain more than 508 bytes of payload may be dropped by some types of\n communication equipment. Refer to RFC 791 and 2460 for an in-depth review."
6935 )]
6936 pub payload: ::heapless::Vec<u8, 508>,
6942 }
6943 impl ::emcyphal_encoding::DataType for OutgoingPacket {
6944 const EXTENT_BYTES: Option<u32> = Some(600);
6946 }
6947 impl ::emcyphal_encoding::Message for OutgoingPacket {}
6948 impl ::emcyphal_encoding::BufferType for OutgoingPacket {
6949 type Buffer = ::emcyphal_encoding::StaticBuffer<561>;
6950 }
6951 impl OutgoingPacket {
6952 #[cfg_attr(
6953 not(doctest),
6954 doc = " [second]\n Modem nodes are required to keep the NAT table entries alive for at least this amount of time, unless the\n table is overflowed, in which case they are allowed to remove least recently used entries in favor of\n newer ones. Modem nodes are required to be able to accommodate at least 100 entries in the NAT table."
6955 )]
6956 pub const NAT_ENTRY_MIN_TTL: u32 = 86400;
6957 }
6958 impl ::emcyphal_encoding::Serialize for OutgoingPacket {
6959 fn size_bits(&self) -> usize {
6960 16 + 16
6961 + 8
6962 + (self.destination_address).len() * 8
6963 + 1
6964 + 1
6965 + 6
6966 + 16
6967 + (self.payload).len() * 8
6968 + 0
6969 }
6970 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
6971 cursor.write_aligned_u16(self.session_id);
6972 cursor.write_aligned_u16(self.destination_port);
6973 cursor.write_aligned_u8((self.destination_address).len() as u8);
6974 cursor.write_bytes(&(self.destination_address)[..]);
6975 cursor.write_bool(self.use_masquerading);
6976 cursor.write_bool(self.use_dtls);
6977 cursor.skip_6();
6978 cursor.write_aligned_u16((self.payload).len() as u16);
6979 cursor.write_bytes(&(self.payload)[..]);
6980 }
6981 }
6982 impl ::emcyphal_encoding::Deserialize for OutgoingPacket {
6983 fn deserialize(
6984 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
6985 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
6986 where
6987 Self: Sized,
6988 {
6989 Ok(OutgoingPacket {
6990 session_id: { cursor.read_u16() as _ },
6991 destination_port: { cursor.read_u16() as _ },
6992 destination_address: {
6993 let length = cursor.read_u8() as _;
6994 if length <= 45 {
6995 let mut elements = ::heapless::Vec::new();
6996 for _ in 0..length {
6997 let _ = elements.push(cursor.read_u8() as _);
6998 }
6999 elements
7000 } else {
7001 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7002 }
7003 },
7004 use_masquerading: { cursor.read_bool() },
7005 use_dtls: { cursor.read_bool() },
7006 payload: {
7007 cursor.skip_6();
7008 let length = cursor.read_u16() as _;
7009 if length <= 508 {
7010 let mut elements = ::heapless::Vec::new();
7011 for _ in 0..length {
7012 let _ = elements.push(cursor.read_u8() as _);
7013 }
7014 elements
7015 } else {
7016 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7017 }
7018 },
7019 })
7020 }
7021 }
7022 }
7023 }
7024 }
7025 pub mod metatransport {
7026 pub mod can {
7027 pub mod arbitration_id_0_1 {
7028 #[cfg_attr(not(doctest), doc = " CAN frame arbitration field.")]
7033 pub enum ArbitrationID {
7034 Base
7037(crate::uavcan::metatransport::can::base_arbitration_id_0_1::BaseArbitrationID)
7038,Extended
7041(crate::uavcan::metatransport::can::extended_arbitration_id_0_1::ExtendedArbitrationID)
7042,}
7043 impl ::emcyphal_encoding::DataType for ArbitrationID {
7044 const EXTENT_BYTES: Option<u32> = None;
7046 }
7047 impl ::emcyphal_encoding::Message for ArbitrationID {}
7048 impl ::emcyphal_encoding::BufferType for ArbitrationID {
7049 type Buffer = ::emcyphal_encoding::StaticBuffer<5>;
7050 }
7051 impl ArbitrationID {}
7052 impl ::emcyphal_encoding::Serialize for ArbitrationID {
7053 fn size_bits(&self) -> usize {
7054 40
7055 }
7056 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7057 match self {
7058 ArbitrationID::Base(inner) => {
7059 cursor.write_aligned_u8(0);
7060 cursor.write_composite(inner);
7061 }
7062 ArbitrationID::Extended(inner) => {
7063 cursor.write_aligned_u8(1);
7064 cursor.write_composite(inner);
7065 }
7066 }
7067 }
7068 }
7069 impl ::emcyphal_encoding::Deserialize for ArbitrationID {
7070 fn deserialize(
7071 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7072 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7073 where
7074 Self: Sized,
7075 {
7076 match cursor.read_aligned_u8() as _ {
7077 0 => Ok(ArbitrationID::Base({ cursor.read_composite()? })),
7078 1 => Ok(ArbitrationID::Extended({ cursor.read_composite()? })),
7079 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
7080 }
7081 }
7082 }
7083 }
7084 pub mod base_arbitration_id_0_1 {
7085 #[cfg_attr(not(doctest), doc = " 11-bit identifier.")]
7090 pub struct BaseArbitrationID {
7091 pub value: u16,
7097 }
7099 impl ::emcyphal_encoding::DataType for BaseArbitrationID {
7100 const EXTENT_BYTES: Option<u32> = None;
7102 }
7103 impl ::emcyphal_encoding::Message for BaseArbitrationID {}
7104 impl ::emcyphal_encoding::BufferType for BaseArbitrationID {
7105 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
7106 }
7107 impl BaseArbitrationID {}
7108 impl ::emcyphal_encoding::Serialize for BaseArbitrationID {
7109 fn size_bits(&self) -> usize {
7110 32
7111 }
7112 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7113 cursor.write_u11(self.value);
7114 cursor.skip_21();
7115 }
7116 }
7117 impl ::emcyphal_encoding::Deserialize for BaseArbitrationID {
7118 fn deserialize(
7119 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7120 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7121 where
7122 Self: Sized,
7123 {
7124 Ok(BaseArbitrationID {
7125 value: { cursor.read_u11() as _ },
7126 })
7127 }
7128 }
7129 }
7130 pub mod data_classic_0_1 {
7131 #[cfg_attr(not(doctest), doc = " Classic data frame payload.")]
7136 pub struct DataClassic {
7137 pub arbitration_id:
7143 crate::uavcan::metatransport::can::arbitration_id_0_1::ArbitrationID,
7144 pub data: ::heapless::Vec<u8, 8>,
7150 }
7151 impl ::emcyphal_encoding::DataType for DataClassic {
7152 const EXTENT_BYTES: Option<u32> = None;
7154 }
7155 impl ::emcyphal_encoding::Message for DataClassic {}
7156 impl ::emcyphal_encoding::BufferType for DataClassic {
7157 type Buffer = ::emcyphal_encoding::StaticBuffer<14>;
7158 }
7159 impl DataClassic {}
7160 impl ::emcyphal_encoding::Serialize for DataClassic {
7161 fn size_bits(&self) -> usize {
7162 40 + 8 + (self.data).len() * 8 + 0
7163 }
7164 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7165 cursor.write_composite(&self.arbitration_id);
7166 cursor.write_aligned_u8((self.data).len() as u8);
7167 cursor.write_bytes(&(self.data)[..]);
7168 }
7169 }
7170 impl ::emcyphal_encoding::Deserialize for DataClassic {
7171 fn deserialize(
7172 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7173 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7174 where
7175 Self: Sized,
7176 {
7177 Ok(DataClassic {
7178 arbitration_id: { cursor.read_composite()? },
7179 data: {
7180 let length = cursor.read_u8() as _;
7181 if length <= 8 {
7182 let mut elements = ::heapless::Vec::new();
7183 for _ in 0..length {
7184 let _ = elements.push(cursor.read_u8() as _);
7185 }
7186 elements
7187 } else {
7188 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7189 }
7190 },
7191 })
7192 }
7193 }
7194 }
7195 pub mod data_fd_0_1 {
7196 #[cfg_attr(not(doctest), doc = " CAN FD data frame payload.")]
7201 pub struct DataFD {
7202 pub arbitration_id:
7208 crate::uavcan::metatransport::can::arbitration_id_0_1::ArbitrationID,
7209 pub data: ::heapless::Vec<u8, 64>,
7215 }
7216 impl ::emcyphal_encoding::DataType for DataFD {
7217 const EXTENT_BYTES: Option<u32> = None;
7219 }
7220 impl ::emcyphal_encoding::Message for DataFD {}
7221 impl ::emcyphal_encoding::BufferType for DataFD {
7222 type Buffer = ::emcyphal_encoding::StaticBuffer<70>;
7223 }
7224 impl DataFD {}
7225 impl ::emcyphal_encoding::Serialize for DataFD {
7226 fn size_bits(&self) -> usize {
7227 40 + 8 + (self.data).len() * 8 + 0
7228 }
7229 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7230 cursor.write_composite(&self.arbitration_id);
7231 cursor.write_aligned_u8((self.data).len() as u8);
7232 cursor.write_bytes(&(self.data)[..]);
7233 }
7234 }
7235 impl ::emcyphal_encoding::Deserialize for DataFD {
7236 fn deserialize(
7237 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7238 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7239 where
7240 Self: Sized,
7241 {
7242 Ok(DataFD {
7243 arbitration_id: { cursor.read_composite()? },
7244 data: {
7245 let length = cursor.read_u8() as _;
7246 if length <= 64 {
7247 let mut elements = ::heapless::Vec::new();
7248 for _ in 0..length {
7249 let _ = elements.push(cursor.read_u8() as _);
7250 }
7251 elements
7252 } else {
7253 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7254 }
7255 },
7256 })
7257 }
7258 }
7259 }
7260 pub mod error_0_1 {
7261 #[cfg_attr(
7266 not(doctest),
7267 doc = " CAN bus error report: either an intentionally generated error frame or a disturbance."
7268 )]
7269 pub struct Error {
7270 }
7272 impl ::emcyphal_encoding::DataType for Error {
7273 const EXTENT_BYTES: Option<u32> = None;
7275 }
7276 impl ::emcyphal_encoding::Message for Error {}
7277 impl ::emcyphal_encoding::BufferType for Error {
7278 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
7279 }
7280 impl Error {}
7281 impl ::emcyphal_encoding::Serialize for Error {
7282 fn size_bits(&self) -> usize {
7283 32
7284 }
7285 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7286 cursor.skip_32();
7287 }
7288 }
7289 impl ::emcyphal_encoding::Deserialize for Error {
7290 fn deserialize(
7291 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7292 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7293 where
7294 Self: Sized,
7295 {
7296 Ok(Error {})
7297 }
7298 }
7299 }
7300 pub mod extended_arbitration_id_0_1 {
7301 #[cfg_attr(not(doctest), doc = " 29-bit identifier.")]
7306 pub struct ExtendedArbitrationID {
7307 pub value: u32,
7313 }
7315 impl ::emcyphal_encoding::DataType for ExtendedArbitrationID {
7316 const EXTENT_BYTES: Option<u32> = None;
7318 }
7319 impl ::emcyphal_encoding::Message for ExtendedArbitrationID {}
7320 impl ::emcyphal_encoding::BufferType for ExtendedArbitrationID {
7321 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
7322 }
7323 impl ExtendedArbitrationID {}
7324 impl ::emcyphal_encoding::Serialize for ExtendedArbitrationID {
7325 fn size_bits(&self) -> usize {
7326 32
7327 }
7328 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7329 cursor.write_u29(self.value);
7330 cursor.skip_3();
7331 }
7332 }
7333 impl ::emcyphal_encoding::Deserialize for ExtendedArbitrationID {
7334 fn deserialize(
7335 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7336 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7337 where
7338 Self: Sized,
7339 {
7340 Ok(ExtendedArbitrationID {
7341 value: { cursor.read_u29() as _ },
7342 })
7343 }
7344 }
7345 }
7346 #[allow(deprecated)]
7347 #[cfg_attr(not(test), deprecated)]
7348 pub mod frame_0_1 {
7349 #[cfg_attr(
7354 not(doctest),
7355 doc = " CAN 2.0 or CAN FD frame representation. This is the top-level data type in its namespace.\n See next version."
7356 )]
7357 #[deprecated]
7358 pub struct Frame {
7359 pub timestamp:
7365 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
7366 pub manifestation:
7372 crate::uavcan::metatransport::can::manifestation_0_1::Manifestation,
7373 }
7374 impl ::emcyphal_encoding::DataType for Frame {
7375 const EXTENT_BYTES: Option<u32> = None;
7377 }
7378 impl ::emcyphal_encoding::Message for Frame {}
7379 impl ::emcyphal_encoding::BufferType for Frame {
7380 type Buffer = ::emcyphal_encoding::StaticBuffer<78>;
7381 }
7382 impl Frame {}
7383 impl ::emcyphal_encoding::Serialize for Frame {
7384 fn size_bits(&self) -> usize {
7385 56 + (self.manifestation).size_bits() + 0
7386 }
7387 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7388 cursor.write_composite(&self.timestamp);
7389 cursor.write_composite(&self.manifestation);
7390 }
7391 }
7392 impl ::emcyphal_encoding::Deserialize for Frame {
7393 fn deserialize(
7394 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7395 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7396 where
7397 Self: Sized,
7398 {
7399 Ok(Frame {
7400 timestamp: { cursor.read_composite()? },
7401 manifestation: { cursor.read_composite()? },
7402 })
7403 }
7404 }
7405 }
7406 pub mod frame_0_2 {
7407 #[cfg_attr(
7412 not(doctest),
7413 doc = " Classic CAN or CAN FD frame representation. This is the top-level data type in its namespace."
7414 )]
7415 pub enum Frame {
7416 #[cfg_attr(not(doctest), doc = " CAN error (intentional or disturbance)")]
7417 Error(crate::uavcan::metatransport::can::error_0_1::Error),
7420 #[cfg_attr(not(doctest), doc = " Bit rate switch flag active")]
7421 DataFd(crate::uavcan::metatransport::can::data_fd_0_1::DataFD),
7424 #[cfg_attr(not(doctest), doc = " Bit rate switch flag not active")]
7425 DataClassic(crate::uavcan::metatransport::can::data_classic_0_1::DataClassic),
7428 #[cfg_attr(
7429 not(doctest),
7430 doc = " Bit rate switch flag not active\n Sealed because the structure is rigidly dictated by an external standard."
7431 )]
7432 RemoteTransmissionRequest(crate::uavcan::metatransport::can::rtr_0_1::RTR),
7435 }
7436 impl ::emcyphal_encoding::DataType for Frame {
7437 const EXTENT_BYTES: Option<u32> = None;
7439 }
7440 impl ::emcyphal_encoding::Message for Frame {}
7441 impl ::emcyphal_encoding::BufferType for Frame {
7442 type Buffer = ::emcyphal_encoding::StaticBuffer<71>;
7443 }
7444 impl Frame {}
7445 impl ::emcyphal_encoding::Serialize for Frame {
7446 fn size_bits(&self) -> usize {
7447 8 + match self {
7448 Frame::Error(inner) => 32,
7449 Frame::DataFd(inner) => (inner).size_bits(),
7450 Frame::DataClassic(inner) => (inner).size_bits(),
7451 Frame::RemoteTransmissionRequest(inner) => 40,
7452 }
7453 }
7454 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7455 match self {
7456 Frame::Error(inner) => {
7457 cursor.write_aligned_u8(0);
7458 cursor.write_composite(inner);
7459 }
7460 Frame::DataFd(inner) => {
7461 cursor.write_aligned_u8(1);
7462 cursor.write_composite(inner);
7463 }
7464 Frame::DataClassic(inner) => {
7465 cursor.write_aligned_u8(2);
7466 cursor.write_composite(inner);
7467 }
7468 Frame::RemoteTransmissionRequest(inner) => {
7469 cursor.write_aligned_u8(3);
7470 cursor.write_composite(inner);
7471 }
7472 }
7473 }
7474 }
7475 impl ::emcyphal_encoding::Deserialize for Frame {
7476 fn deserialize(
7477 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7478 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7479 where
7480 Self: Sized,
7481 {
7482 match cursor.read_aligned_u8() as _ {
7483 0 => Ok(Frame::Error({ cursor.read_composite()? })),
7484 1 => Ok(Frame::DataFd({ cursor.read_composite()? })),
7485 2 => Ok(Frame::DataClassic({ cursor.read_composite()? })),
7486 3 => Ok(Frame::RemoteTransmissionRequest({
7487 cursor.read_composite()?
7488 })),
7489 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
7490 }
7491 }
7492 }
7493 }
7494 #[allow(deprecated)]
7495 #[cfg_attr(not(test), deprecated)]
7496 pub mod manifestation_0_1 {
7497 #[cfg_attr(
7502 not(doctest),
7503 doc = " CAN frame properties that can be manifested on the bus.\n See Frame.0.2 as a replacement"
7504 )]
7505 #[deprecated]
7506 pub enum Manifestation {
7507 #[cfg_attr(not(doctest), doc = " CAN error (intentional or disturbance)")]
7508 Error(crate::uavcan::metatransport::can::error_0_1::Error),
7511 #[cfg_attr(not(doctest), doc = " Bit rate switch flag active")]
7512 DataFd(crate::uavcan::metatransport::can::data_fd_0_1::DataFD),
7515 #[cfg_attr(not(doctest), doc = " Bit rate switch flag not active")]
7516 DataClassic(crate::uavcan::metatransport::can::data_classic_0_1::DataClassic),
7519 #[cfg_attr(not(doctest), doc = " Bit rate switch flag not active")]
7520 RemoteTransmissionRequest(crate::uavcan::metatransport::can::rtr_0_1::RTR),
7523 }
7524 impl ::emcyphal_encoding::DataType for Manifestation {
7525 const EXTENT_BYTES: Option<u32> = None;
7527 }
7528 impl ::emcyphal_encoding::Message for Manifestation {}
7529 impl ::emcyphal_encoding::BufferType for Manifestation {
7530 type Buffer = ::emcyphal_encoding::StaticBuffer<71>;
7531 }
7532 impl Manifestation {}
7533 impl ::emcyphal_encoding::Serialize for Manifestation {
7534 fn size_bits(&self) -> usize {
7535 8 + match self {
7536 Manifestation::Error(inner) => 32,
7537 Manifestation::DataFd(inner) => (inner).size_bits(),
7538 Manifestation::DataClassic(inner) => (inner).size_bits(),
7539 Manifestation::RemoteTransmissionRequest(inner) => 40,
7540 }
7541 }
7542 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7543 match self {
7544 Manifestation::Error(inner) => {
7545 cursor.write_aligned_u8(0);
7546 cursor.write_composite(inner);
7547 }
7548 Manifestation::DataFd(inner) => {
7549 cursor.write_aligned_u8(1);
7550 cursor.write_composite(inner);
7551 }
7552 Manifestation::DataClassic(inner) => {
7553 cursor.write_aligned_u8(2);
7554 cursor.write_composite(inner);
7555 }
7556 Manifestation::RemoteTransmissionRequest(inner) => {
7557 cursor.write_aligned_u8(3);
7558 cursor.write_composite(inner);
7559 }
7560 }
7561 }
7562 }
7563 impl ::emcyphal_encoding::Deserialize for Manifestation {
7564 fn deserialize(
7565 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7566 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7567 where
7568 Self: Sized,
7569 {
7570 match cursor.read_aligned_u8() as _ {
7571 0 => Ok(Manifestation::Error({ cursor.read_composite()? })),
7572 1 => Ok(Manifestation::DataFd({ cursor.read_composite()? })),
7573 2 => Ok(Manifestation::DataClassic({ cursor.read_composite()? })),
7574 3 => Ok(Manifestation::RemoteTransmissionRequest({
7575 cursor.read_composite()?
7576 })),
7577 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
7578 }
7579 }
7580 }
7581 }
7582 pub mod rtr_0_1 {
7583 #[cfg_attr(
7588 not(doctest),
7589 doc = " Classic remote transmission request (not defined for CAN FD)."
7590 )]
7591 pub struct RTR {
7592 pub arbitration_id:
7598 crate::uavcan::metatransport::can::arbitration_id_0_1::ArbitrationID,
7599 }
7600 impl ::emcyphal_encoding::DataType for RTR {
7601 const EXTENT_BYTES: Option<u32> = None;
7603 }
7604 impl ::emcyphal_encoding::Message for RTR {}
7605 impl ::emcyphal_encoding::BufferType for RTR {
7606 type Buffer = ::emcyphal_encoding::StaticBuffer<5>;
7607 }
7608 impl RTR {}
7609 impl ::emcyphal_encoding::Serialize for RTR {
7610 fn size_bits(&self) -> usize {
7611 40
7612 }
7613 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7614 cursor.write_composite(&self.arbitration_id);
7615 }
7616 }
7617 impl ::emcyphal_encoding::Deserialize for RTR {
7618 fn deserialize(
7619 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7620 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7621 where
7622 Self: Sized,
7623 {
7624 Ok(RTR {
7625 arbitration_id: { cursor.read_composite()? },
7626 })
7627 }
7628 }
7629 }
7630 }
7631 pub mod ethernet {
7632 pub mod ether_type_0_1 {
7633 #[cfg_attr(
7638 not(doctest),
7639 doc = " Standard EtherType constants as defined by IEEE Registration Authority and IANA.\n This list is only a small subset of constants that are considered to be relevant for Cyphal."
7640 )]
7641 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
7642 #[repr(C, packed)]
7643 pub struct EtherType {
7644 pub value: u16,
7650 }
7651 impl ::emcyphal_encoding::DataType for EtherType {
7652 const EXTENT_BYTES: Option<u32> = None;
7654 }
7655 impl ::emcyphal_encoding::Message for EtherType {}
7656 impl ::emcyphal_encoding::BufferType for EtherType {
7657 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
7658 }
7659 impl EtherType {
7660 pub const IP_V4: u16 = 2048;
7661 pub const ARP: u16 = 2054;
7662 pub const IP_V6: u16 = 34525;
7663 }
7664 impl ::emcyphal_encoding::Serialize for EtherType {
7665 fn size_bits(&self) -> usize {
7666 16
7667 }
7668 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7669 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
7670 }
7671 }
7672 impl ::emcyphal_encoding::Deserialize for EtherType {
7673 fn deserialize(
7674 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7675 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7676 where
7677 Self: Sized,
7678 {
7679 Ok(Self::deserialize_zero_copy(cursor))
7680 }
7681 }
7682 #[test]
7683 fn test_layout() {
7684 assert_eq!(::core::mem::size_of::<EtherType>() * 8, 16);
7685 assert_eq!(::core::mem::offset_of!(EtherType, value) * 8, 0);
7686 }
7687 }
7688 pub mod frame_0_1 {
7689 #[cfg_attr(
7694 not(doctest),
7695 doc = " IEEE 802.3 Ethernet frame encapsulation.\n In terms of libpcap/tcpdump, the corresponding link type is LINKTYPE_ETHERNET/DLT_EN10MB."
7696 )]
7697 pub struct Frame {
7698 pub destination: [u8; 6],
7704 pub source: [u8; 6],
7710 pub ethertype:
7716 crate::uavcan::metatransport::ethernet::ether_type_0_1::EtherType,
7717 #[cfg_attr(
7718 not(doctest),
7719 doc = " Supports conventional jumbo frames (up to 9 KiB)."
7720 )]
7721 pub payload: ::heapless::Vec<u8, 9216>,
7727 }
7728 impl ::emcyphal_encoding::DataType for Frame {
7729 const EXTENT_BYTES: Option<u32> = None;
7731 }
7732 impl ::emcyphal_encoding::Message for Frame {}
7733 impl ::emcyphal_encoding::BufferType for Frame {
7734 type Buffer = ::emcyphal_encoding::StaticBuffer<9232>;
7735 }
7736 impl Frame {}
7737 impl ::emcyphal_encoding::Serialize for Frame {
7738 fn size_bits(&self) -> usize {
7739 (self.destination).len() * 8
7740 + (self.source).len() * 8
7741 + 16
7742 + 16
7743 + (self.payload).len() * 8
7744 + 0
7745 }
7746 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7747 cursor.write_bytes(&(self.destination)[..]);
7748 cursor.write_bytes(&(self.source)[..]);
7749 cursor.write_composite(&self.ethertype);
7750 cursor.write_aligned_u16((self.payload).len() as u16);
7751 cursor.write_bytes(&(self.payload)[..]);
7752 }
7753 }
7754 impl ::emcyphal_encoding::Deserialize for Frame {
7755 fn deserialize(
7756 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7757 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7758 where
7759 Self: Sized,
7760 {
7761 Ok(Frame {
7762 destination: {
7763 [
7764 cursor.read_u8() as _,
7765 cursor.read_u8() as _,
7766 cursor.read_u8() as _,
7767 cursor.read_u8() as _,
7768 cursor.read_u8() as _,
7769 cursor.read_u8() as _,
7770 ]
7771 },
7772 source: {
7773 [
7774 cursor.read_u8() as _,
7775 cursor.read_u8() as _,
7776 cursor.read_u8() as _,
7777 cursor.read_u8() as _,
7778 cursor.read_u8() as _,
7779 cursor.read_u8() as _,
7780 ]
7781 },
7782 ethertype: { cursor.read_composite()? },
7783 payload: {
7784 let length = cursor.read_u16() as _;
7785 if length <= 9216 {
7786 let mut elements = ::heapless::Vec::new();
7787 for _ in 0..length {
7788 let _ = elements.push(cursor.read_u8() as _);
7789 }
7790 elements
7791 } else {
7792 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7793 }
7794 },
7795 })
7796 }
7797 }
7798 }
7799 }
7800 pub mod serial {
7801 #[allow(deprecated)]
7802 #[cfg_attr(not(test), deprecated)]
7803 pub mod fragment_0_1 {
7804 #[cfg_attr(
7809 not(doctest),
7810 doc = " A chunk of raw bytes exchanged over a serial transport. Serial links do not support framing natively.\n The chunk may be of arbitrary size.\n See next version."
7811 )]
7812 #[deprecated]
7813 pub struct Fragment {
7814 pub timestamp:
7820 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
7821 pub data: ::heapless::Vec<u8, 256>,
7827 }
7828 impl ::emcyphal_encoding::DataType for Fragment {
7829 const EXTENT_BYTES: Option<u32> = None;
7831 }
7832 impl ::emcyphal_encoding::Message for Fragment {}
7833 impl ::emcyphal_encoding::BufferType for Fragment {
7834 type Buffer = ::emcyphal_encoding::StaticBuffer<265>;
7835 }
7836 impl Fragment {
7837 pub const CAPACITY_BYTES: u16 = 256;
7838 }
7839 impl ::emcyphal_encoding::Serialize for Fragment {
7840 fn size_bits(&self) -> usize {
7841 56 + 16 + (self.data).len() * 8 + 0
7842 }
7843 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7844 cursor.write_composite(&self.timestamp);
7845 cursor.write_aligned_u16((self.data).len() as u16);
7846 cursor.write_bytes(&(self.data)[..]);
7847 }
7848 }
7849 impl ::emcyphal_encoding::Deserialize for Fragment {
7850 fn deserialize(
7851 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7852 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7853 where
7854 Self: Sized,
7855 {
7856 Ok(Fragment {
7857 timestamp: { cursor.read_composite()? },
7858 data: {
7859 let length = cursor.read_u16() as _;
7860 if length <= 256 {
7861 let mut elements = ::heapless::Vec::new();
7862 for _ in 0..length {
7863 let _ = elements.push(cursor.read_u8() as _);
7864 }
7865 elements
7866 } else {
7867 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7868 }
7869 },
7870 })
7871 }
7872 }
7873 }
7874 pub mod fragment_0_2 {
7875 #[cfg_attr(
7880 not(doctest),
7881 doc = " A chunk of raw bytes exchanged over a serial transport. Serial links do not support framing natively.\n The chunk may be of arbitrary size.\n\n If this data type is used to encapsulate Cyphal/serial, then it is recommended to ensure that each message\n contains at most one Cyphal/serial transport frame (frames are separated by zero-valued delimiter bytes)."
7882 )]
7883 pub struct Fragment {
7884 pub data: ::heapless::Vec<u8, 2048>,
7890 }
7891 impl ::emcyphal_encoding::DataType for Fragment {
7892 const EXTENT_BYTES: Option<u32> = None;
7894 }
7895 impl ::emcyphal_encoding::Message for Fragment {}
7896 impl ::emcyphal_encoding::BufferType for Fragment {
7897 type Buffer = ::emcyphal_encoding::StaticBuffer<2050>;
7898 }
7899 impl Fragment {
7900 pub const CAPACITY_BYTES: u16 = 2048;
7901 }
7902 impl ::emcyphal_encoding::Serialize for Fragment {
7903 fn size_bits(&self) -> usize {
7904 16 + (self.data).len() * 8 + 0
7905 }
7906 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7907 cursor.write_aligned_u16((self.data).len() as u16);
7908 cursor.write_bytes(&(self.data)[..]);
7909 }
7910 }
7911 impl ::emcyphal_encoding::Deserialize for Fragment {
7912 fn deserialize(
7913 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
7914 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
7915 where
7916 Self: Sized,
7917 {
7918 Ok(Fragment {
7919 data: {
7920 let length = cursor.read_u16() as _;
7921 if length <= 2048 {
7922 let mut elements = ::heapless::Vec::new();
7923 for _ in 0..length {
7924 let _ = elements.push(cursor.read_u8() as _);
7925 }
7926 elements
7927 } else {
7928 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
7929 }
7930 },
7931 })
7932 }
7933 }
7934 }
7935 }
7936 pub mod udp {
7937 #[allow(deprecated)]
7938 #[cfg_attr(not(test), deprecated)]
7939 pub mod endpoint_0_1 {
7940 #[cfg_attr(
7945 not(doctest),
7946 doc = " A UDP/IP endpoint address specification.\n Replaced by uavcan.metatransport.ethernet"
7947 )]
7948 #[deprecated]
7949 pub struct Endpoint {
7950 #[cfg_attr(
7951 not(doctest),
7952 doc = " The IP address of the host in the network byte order (big endian).\n IPv6 addresses are represented as-is.\n IPv4 addresses are represented using IPv4-mapped IPv6 addresses."
7953 )]
7954 pub ip_address: [u8; 16],
7960 #[cfg_attr(
7961 not(doctest),
7962 doc = " MAC address of the host in the network byte order (big endian)."
7963 )]
7964 pub mac_address: [u8; 6],
7970 #[cfg_attr(not(doctest), doc = " The UDP port number.")]
7971 pub port: u16,
7977 }
7979 impl ::emcyphal_encoding::DataType for Endpoint {
7980 const EXTENT_BYTES: Option<u32> = None;
7982 }
7983 impl ::emcyphal_encoding::Message for Endpoint {}
7984 impl ::emcyphal_encoding::BufferType for Endpoint {
7985 type Buffer = ::emcyphal_encoding::StaticBuffer<32>;
7986 }
7987 impl Endpoint {}
7988 impl ::emcyphal_encoding::Serialize for Endpoint {
7989 fn size_bits(&self) -> usize {
7990 256
7991 }
7992 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
7993 cursor.write_bytes(&(self.ip_address)[..]);
7994 cursor.write_bytes(&(self.mac_address)[..]);
7995 cursor.write_aligned_u16(self.port);
7996 cursor.skip_64();
7997 }
7998 }
7999 impl ::emcyphal_encoding::Deserialize for Endpoint {
8000 fn deserialize(
8001 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8002 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8003 where
8004 Self: Sized,
8005 {
8006 Ok(Endpoint {
8007 ip_address: {
8008 [
8009 cursor.read_u8() as _,
8010 cursor.read_u8() as _,
8011 cursor.read_u8() as _,
8012 cursor.read_u8() as _,
8013 cursor.read_u8() as _,
8014 cursor.read_u8() as _,
8015 cursor.read_u8() as _,
8016 cursor.read_u8() as _,
8017 cursor.read_u8() as _,
8018 cursor.read_u8() as _,
8019 cursor.read_u8() as _,
8020 cursor.read_u8() as _,
8021 cursor.read_u8() as _,
8022 cursor.read_u8() as _,
8023 cursor.read_u8() as _,
8024 cursor.read_u8() as _,
8025 ]
8026 },
8027 mac_address: {
8028 [
8029 cursor.read_u8() as _,
8030 cursor.read_u8() as _,
8031 cursor.read_u8() as _,
8032 cursor.read_u8() as _,
8033 cursor.read_u8() as _,
8034 cursor.read_u8() as _,
8035 ]
8036 },
8037 port: { cursor.read_u16() as _ },
8038 })
8039 }
8040 }
8041 }
8042 #[allow(deprecated)]
8043 #[cfg_attr(not(test), deprecated)]
8044 pub mod frame_0_1 {
8045 #[cfg_attr(
8050 not(doctest),
8051 doc = " A generic UDP/IP frame.\n Jumboframes are supported in the interest of greater application compatibility.\n Replaced by uavcan.metatransport.ethernet"
8052 )]
8053 #[deprecated]
8054 pub struct Frame {
8055 pub timestamp:
8061 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
8062 pub source: crate::uavcan::metatransport::udp::endpoint_0_1::Endpoint,
8069 pub destination: crate::uavcan::metatransport::udp::endpoint_0_1::Endpoint,
8075 pub data: ::heapless::Vec<u8, 9188>,
8081 }
8082 impl ::emcyphal_encoding::DataType for Frame {
8083 const EXTENT_BYTES: Option<u32> = Some(10240);
8085 }
8086 impl ::emcyphal_encoding::Message for Frame {}
8087 impl ::emcyphal_encoding::BufferType for Frame {
8088 type Buffer = ::emcyphal_encoding::StaticBuffer<9262>;
8089 }
8090 impl Frame {
8091 #[cfg_attr(
8092 not(doctest),
8093 doc = " Max jumbo frame 9 KiB, IP header min 20 B, UDP header 8 B."
8094 )]
8095 pub const MTU: u16 = 9188;
8096 }
8097 impl ::emcyphal_encoding::Serialize for Frame {
8098 fn size_bits(&self) -> usize {
8099 56 + 8 + 256 + 256 + 16 + (self.data).len() * 8 + 0
8100 }
8101 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8102 cursor.write_composite(&self.timestamp);
8103 cursor.skip_8();
8104 cursor.write_composite(&self.source);
8105 cursor.write_composite(&self.destination);
8106 cursor.write_aligned_u16((self.data).len() as u16);
8107 cursor.write_bytes(&(self.data)[..]);
8108 }
8109 }
8110 impl ::emcyphal_encoding::Deserialize for Frame {
8111 fn deserialize(
8112 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8113 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8114 where
8115 Self: Sized,
8116 {
8117 Ok(Frame {
8118 timestamp: { cursor.read_composite()? },
8119 source: {
8120 cursor.skip_8();
8121 cursor.read_composite()?
8122 },
8123 destination: { cursor.read_composite()? },
8124 data: {
8125 let length = cursor.read_u16() as _;
8126 if length <= 9188 {
8127 let mut elements = ::heapless::Vec::new();
8128 for _ in 0..length {
8129 let _ = elements.push(cursor.read_u8() as _);
8130 }
8131 elements
8132 } else {
8133 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8134 }
8135 },
8136 })
8137 }
8138 }
8139 }
8140 }
8141 }
8142 pub mod node {
8143 #[allow(deprecated)]
8144 #[cfg_attr(not(test), deprecated)]
8145 pub mod execute_command_1_0 {
8146 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
8147 #[deprecated]
8148 pub const SERVICE: ::emcyphal_core::ServiceId =
8149 ::emcyphal_core::ServiceId::from_u16_truncating(435);
8150
8151 #[cfg_attr(
8156 not(doctest),
8157 doc = " Instructs the server node to execute or commence execution of a simple predefined command.\n All standard commands are optional; i.e., not guaranteed to be supported by all nodes."
8158 )]
8159 #[deprecated]
8160 pub struct ExecuteCommandRequest {
8161 #[cfg_attr(
8162 not(doctest),
8163 doc = " Standard pre-defined commands are at the top of the range (defined below).\n Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).\n Vendor-specific commands shall not use identifiers above 32767."
8164 )]
8165 pub command: u16,
8171 #[cfg_attr(
8172 not(doctest),
8173 doc = " A string parameter supplied to the command. The format and interpretation is command-specific.\n The standard commands do not use this field (ignore it), excepting the following:\n - COMMAND_BEGIN_SOFTWARE_UPDATE\n Two CAN FD frames max"
8174 )]
8175 pub parameter: ::heapless::Vec<u8, 112>,
8181 }
8182 impl ::emcyphal_encoding::DataType for ExecuteCommandRequest {
8183 const EXTENT_BYTES: Option<u32> = Some(300);
8185 }
8186 impl ::emcyphal_encoding::Request for ExecuteCommandRequest {}
8187 impl ::emcyphal_encoding::BufferType for ExecuteCommandRequest {
8188 type Buffer = ::emcyphal_encoding::StaticBuffer<115>;
8189 }
8190 impl ExecuteCommandRequest {
8191 #[cfg_attr(
8192 not(doctest),
8193 doc = " Reboot the node.\n Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset."
8194 )]
8195 pub const COMMAND_RESTART: u16 = 65535;
8196 #[cfg_attr(
8197 not(doctest),
8198 doc = " Shut down the node; further access will not be possible until the power is turned back on."
8199 )]
8200 pub const COMMAND_POWER_OFF: u16 = 65534;
8201 #[cfg_attr(
8202 not(doctest),
8203 doc = " Begin the software update process using uavcan.file.Read. This command makes use of the \"parameter\" field below.\n The parameter contains the path to the new software image file to be downloaded by the server from the client\n using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and\n the server.\n\n Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the\n software update process. If that is deemed impossible, the command will be rejected with one of the\n error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently\n on-duty and a sudden interruption of its activities is considered unsafe, and so on).\n If an update process is already underway, the updatee should abort the process and restart with the new file,\n unless the updatee can determine that the specified file is the same file that is already being downloaded,\n in which case it is allowed to respond SUCCESS and continue the old update process.\n If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and\n initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file\n is transferred fully (please refer to the documentation for that data type for more information about its usage).\n\n While the software is being updated, the updatee should set its mode (the field \"mode\" in uavcan.node.Heartbeat)\n to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.\n\n It is recognized that most systems will have to interrupt their normal services to perform the software update\n (unless some form of software hot swapping is implemented, as is the case in some high-availability systems).\n\n Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware\n and start the embedded bootloader (although other approaches are possible as well). In that case,\n while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be\n MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities\n are currently underway. For example, if the update process failed and the bootloader cannot load the software,\n the same mode MODE_SOFTWARE_UPDATE will be reported.\n It is also recognized that in a microcontroller setting, the application that served the update request will have\n to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to\n the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification."
8204 )]
8205 pub const COMMAND_BEGIN_SOFTWARE_UPDATE: u16 = 65533;
8206 #[cfg_attr(
8207 not(doctest),
8208 doc = " Return the node's configuration back to the factory default settings (may require restart).\n Due to the uncertainty whether a restart is required, generic interfaces should always force a restart."
8209 )]
8210 pub const COMMAND_FACTORY_RESET: u16 = 65532;
8211 #[cfg_attr(
8212 not(doctest),
8213 doc = " Cease activities immediately, enter a safe state until restarted.\n Further operation may no longer be possible until a restart command is executed."
8214 )]
8215 pub const COMMAND_EMERGENCY_STOP: u16 = 65531;
8216 #[cfg_attr(
8217 not(doctest),
8218 doc = " This command instructs the node to store the current configuration parameter values and other persistent states\n to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for\n this command by committing all such data to the non-volatile memory automatically as necessary. However, some\n nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always\n invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic\n persistence management."
8219 )]
8220 pub const COMMAND_STORE_PERSISTENT_STATES: u16 = 65530;
8221 }
8222 impl ::emcyphal_encoding::Serialize for ExecuteCommandRequest {
8223 fn size_bits(&self) -> usize {
8224 16 + 8 + (self.parameter).len() * 8 + 0
8225 }
8226 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8227 cursor.write_aligned_u16(self.command);
8228 cursor.write_aligned_u8((self.parameter).len() as u8);
8229 cursor.write_bytes(&(self.parameter)[..]);
8230 }
8231 }
8232 impl ::emcyphal_encoding::Deserialize for ExecuteCommandRequest {
8233 fn deserialize(
8234 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8235 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8236 where
8237 Self: Sized,
8238 {
8239 Ok(ExecuteCommandRequest {
8240 command: { cursor.read_u16() as _ },
8241 parameter: {
8242 let length = cursor.read_u8() as _;
8243 if length <= 112 {
8244 let mut elements = ::heapless::Vec::new();
8245 for _ in 0..length {
8246 let _ = elements.push(cursor.read_u8() as _);
8247 }
8248 elements
8249 } else {
8250 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8251 }
8252 },
8253 })
8254 }
8255 }
8256
8257 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
8262 #[repr(C, packed)]
8263 #[deprecated]
8264 pub struct ExecuteCommandResponse {
8265 #[cfg_attr(not(doctest), doc = " The result of the request.")]
8266 pub status: u8,
8272 }
8273 impl ::emcyphal_encoding::DataType for ExecuteCommandResponse {
8274 const EXTENT_BYTES: Option<u32> = Some(48);
8276 }
8277 impl ::emcyphal_encoding::Response for ExecuteCommandResponse {}
8278 impl ::emcyphal_encoding::BufferType for ExecuteCommandResponse {
8279 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
8280 }
8281 impl ExecuteCommandResponse {
8282 #[cfg_attr(not(doctest), doc = " Started or executed successfully")]
8283 pub const STATUS_SUCCESS: u8 = 0;
8284 #[cfg_attr(
8285 not(doctest),
8286 doc = " Could not start or the desired outcome could not be reached"
8287 )]
8288 pub const STATUS_FAILURE: u8 = 1;
8289 #[cfg_attr(not(doctest), doc = " Denied due to lack of authorization")]
8290 pub const STATUS_NOT_AUTHORIZED: u8 = 2;
8291 #[cfg_attr(
8292 not(doctest),
8293 doc = " The requested command is not known or not supported"
8294 )]
8295 pub const STATUS_BAD_COMMAND: u8 = 3;
8296 #[cfg_attr(
8297 not(doctest),
8298 doc = " The supplied parameter cannot be used with the selected command"
8299 )]
8300 pub const STATUS_BAD_PARAMETER: u8 = 4;
8301 #[cfg_attr(
8302 not(doctest),
8303 doc = " The current state of the node does not permit execution of this command"
8304 )]
8305 pub const STATUS_BAD_STATE: u8 = 5;
8306 #[cfg_attr(
8307 not(doctest),
8308 doc = " The operation should have succeeded but an unexpected failure occurred"
8309 )]
8310 pub const STATUS_INTERNAL_ERROR: u8 = 6;
8311 }
8312 impl ::emcyphal_encoding::Serialize for ExecuteCommandResponse {
8313 fn size_bits(&self) -> usize {
8314 8
8315 }
8316 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8317 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
8318 }
8319 }
8320 impl ::emcyphal_encoding::Deserialize for ExecuteCommandResponse {
8321 fn deserialize(
8322 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8323 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8324 where
8325 Self: Sized,
8326 {
8327 Ok(Self::deserialize_zero_copy(cursor))
8328 }
8329 }
8330 #[test]
8331 fn test_layout() {
8332 assert_eq!(::core::mem::size_of::<ExecuteCommandResponse>() * 8, 8);
8333 assert_eq!(
8334 ::core::mem::offset_of!(ExecuteCommandResponse, status) * 8,
8335 0
8336 );
8337 }
8338 }
8339 #[allow(deprecated)]
8340 #[cfg_attr(not(test), deprecated)]
8341 pub mod execute_command_1_1 {
8342 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
8343 #[deprecated]
8344 pub const SERVICE: ::emcyphal_core::ServiceId =
8345 ::emcyphal_core::ServiceId::from_u16_truncating(435);
8346
8347 #[cfg_attr(
8352 not(doctest),
8353 doc = " Instructs the server node to execute or commence execution of a simple predefined command.\n All standard commands are optional; i.e., not guaranteed to be supported by all nodes."
8354 )]
8355 #[deprecated]
8356 pub struct ExecuteCommandRequest {
8357 #[cfg_attr(
8358 not(doctest),
8359 doc = " Standard pre-defined commands are at the top of the range (defined below).\n Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).\n Vendor-specific commands shall not use identifiers above 32767."
8360 )]
8361 pub command: u16,
8367 #[cfg_attr(
8368 not(doctest),
8369 doc = " A string parameter supplied to the command. The format and interpretation is command-specific.\n The standard commands do not use this field (ignore it), excepting the following:\n - COMMAND_BEGIN_SOFTWARE_UPDATE"
8370 )]
8371 pub parameter: ::heapless::Vec<u8, 255>,
8377 }
8378 impl ::emcyphal_encoding::DataType for ExecuteCommandRequest {
8379 const EXTENT_BYTES: Option<u32> = Some(300);
8381 }
8382 impl ::emcyphal_encoding::Request for ExecuteCommandRequest {}
8383 impl ::emcyphal_encoding::BufferType for ExecuteCommandRequest {
8384 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
8385 }
8386 impl ExecuteCommandRequest {
8387 #[cfg_attr(
8388 not(doctest),
8389 doc = " Reboot the node.\n Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset."
8390 )]
8391 pub const COMMAND_RESTART: u16 = 65535;
8392 #[cfg_attr(
8393 not(doctest),
8394 doc = " Shut down the node; further access will not be possible until the power is turned back on."
8395 )]
8396 pub const COMMAND_POWER_OFF: u16 = 65534;
8397 #[cfg_attr(
8398 not(doctest),
8399 doc = " Begin the software update process using uavcan.file.Read. This command makes use of the \"parameter\" field below.\n The parameter contains the path to the new software image file to be downloaded by the server from the client\n using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and\n the server.\n\n Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the\n software update process. If that is deemed impossible, the command will be rejected with one of the\n error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently\n on-duty and a sudden interruption of its activities is considered unsafe, and so on).\n If an update process is already underway, the updatee should abort the process and restart with the new file,\n unless the updatee can determine that the specified file is the same file that is already being downloaded,\n in which case it is allowed to respond SUCCESS and continue the old update process.\n If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and\n initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file\n is transferred fully (please refer to the documentation for that data type for more information about its usage).\n\n While the software is being updated, the updatee should set its mode (the field \"mode\" in uavcan.node.Heartbeat)\n to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.\n\n It is recognized that most systems will have to interrupt their normal services to perform the software update\n (unless some form of software hot swapping is implemented, as is the case in some high-availability systems).\n\n Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware\n and start the embedded bootloader (although other approaches are possible as well). In that case,\n while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be\n MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities\n are currently underway. For example, if the update process failed and the bootloader cannot load the software,\n the same mode MODE_SOFTWARE_UPDATE will be reported.\n It is also recognized that in a microcontroller setting, the application that served the update request will have\n to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to\n the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification."
8400 )]
8401 pub const COMMAND_BEGIN_SOFTWARE_UPDATE: u16 = 65533;
8402 #[cfg_attr(
8403 not(doctest),
8404 doc = " Return the node's configuration back to the factory default settings (may require restart).\n Due to the uncertainty whether a restart is required, generic interfaces should always force a restart."
8405 )]
8406 pub const COMMAND_FACTORY_RESET: u16 = 65532;
8407 #[cfg_attr(
8408 not(doctest),
8409 doc = " Cease activities immediately, enter a safe state until restarted.\n Further operation may no longer be possible until a restart command is executed."
8410 )]
8411 pub const COMMAND_EMERGENCY_STOP: u16 = 65531;
8412 #[cfg_attr(
8413 not(doctest),
8414 doc = " This command instructs the node to store the current configuration parameter values and other persistent states\n to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for\n this command by committing all such data to the non-volatile memory automatically as necessary. However, some\n nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always\n invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic\n persistence management."
8415 )]
8416 pub const COMMAND_STORE_PERSISTENT_STATES: u16 = 65530;
8417 }
8418 impl ::emcyphal_encoding::Serialize for ExecuteCommandRequest {
8419 fn size_bits(&self) -> usize {
8420 16 + 8 + (self.parameter).len() * 8 + 0
8421 }
8422 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8423 cursor.write_aligned_u16(self.command);
8424 cursor.write_aligned_u8((self.parameter).len() as u8);
8425 cursor.write_bytes(&(self.parameter)[..]);
8426 }
8427 }
8428 impl ::emcyphal_encoding::Deserialize for ExecuteCommandRequest {
8429 fn deserialize(
8430 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8431 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8432 where
8433 Self: Sized,
8434 {
8435 Ok(ExecuteCommandRequest {
8436 command: { cursor.read_u16() as _ },
8437 parameter: {
8438 let length = cursor.read_u8() as _;
8439 if length <= 255 {
8440 let mut elements = ::heapless::Vec::new();
8441 for _ in 0..length {
8442 let _ = elements.push(cursor.read_u8() as _);
8443 }
8444 elements
8445 } else {
8446 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8447 }
8448 },
8449 })
8450 }
8451 }
8452
8453 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
8458 #[repr(C, packed)]
8459 #[deprecated]
8460 pub struct ExecuteCommandResponse {
8461 #[cfg_attr(not(doctest), doc = " The result of the request.")]
8462 pub status: u8,
8468 }
8469 impl ::emcyphal_encoding::DataType for ExecuteCommandResponse {
8470 const EXTENT_BYTES: Option<u32> = Some(48);
8472 }
8473 impl ::emcyphal_encoding::Response for ExecuteCommandResponse {}
8474 impl ::emcyphal_encoding::BufferType for ExecuteCommandResponse {
8475 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
8476 }
8477 impl ExecuteCommandResponse {
8478 #[cfg_attr(not(doctest), doc = " Started or executed successfully")]
8479 pub const STATUS_SUCCESS: u8 = 0;
8480 #[cfg_attr(
8481 not(doctest),
8482 doc = " Could not start or the desired outcome could not be reached"
8483 )]
8484 pub const STATUS_FAILURE: u8 = 1;
8485 #[cfg_attr(not(doctest), doc = " Denied due to lack of authorization")]
8486 pub const STATUS_NOT_AUTHORIZED: u8 = 2;
8487 #[cfg_attr(
8488 not(doctest),
8489 doc = " The requested command is not known or not supported"
8490 )]
8491 pub const STATUS_BAD_COMMAND: u8 = 3;
8492 #[cfg_attr(
8493 not(doctest),
8494 doc = " The supplied parameter cannot be used with the selected command"
8495 )]
8496 pub const STATUS_BAD_PARAMETER: u8 = 4;
8497 #[cfg_attr(
8498 not(doctest),
8499 doc = " The current state of the node does not permit execution of this command"
8500 )]
8501 pub const STATUS_BAD_STATE: u8 = 5;
8502 #[cfg_attr(
8503 not(doctest),
8504 doc = " The operation should have succeeded but an unexpected failure occurred"
8505 )]
8506 pub const STATUS_INTERNAL_ERROR: u8 = 6;
8507 }
8508 impl ::emcyphal_encoding::Serialize for ExecuteCommandResponse {
8509 fn size_bits(&self) -> usize {
8510 8
8511 }
8512 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8513 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
8514 }
8515 }
8516 impl ::emcyphal_encoding::Deserialize for ExecuteCommandResponse {
8517 fn deserialize(
8518 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8519 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8520 where
8521 Self: Sized,
8522 {
8523 Ok(Self::deserialize_zero_copy(cursor))
8524 }
8525 }
8526 #[test]
8527 fn test_layout() {
8528 assert_eq!(::core::mem::size_of::<ExecuteCommandResponse>() * 8, 8);
8529 assert_eq!(
8530 ::core::mem::offset_of!(ExecuteCommandResponse, status) * 8,
8531 0
8532 );
8533 }
8534 }
8535 #[allow(deprecated)]
8536 #[cfg_attr(not(test), deprecated)]
8537 pub mod execute_command_1_2 {
8538 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
8539 #[deprecated]
8540 pub const SERVICE: ::emcyphal_core::ServiceId =
8541 ::emcyphal_core::ServiceId::from_u16_truncating(435);
8542
8543 #[cfg_attr(
8548 not(doctest),
8549 doc = " Instructs the server node to execute or commence execution of a simple predefined command.\n All standard commands are optional; i.e., not guaranteed to be supported by all nodes."
8550 )]
8551 #[deprecated]
8552 pub struct ExecuteCommandRequest {
8553 #[cfg_attr(
8554 not(doctest),
8555 doc = " Standard pre-defined commands are at the top of the range (defined below).\n Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).\n Vendor-specific commands shall not use identifiers above 32767."
8556 )]
8557 pub command: u16,
8563 #[cfg_attr(
8564 not(doctest),
8565 doc = " A string parameter supplied to the command. The format and interpretation is command-specific.\n The standard commands do not use this field (ignore it), excepting the following:\n - COMMAND_BEGIN_SOFTWARE_UPDATE"
8566 )]
8567 pub parameter: ::heapless::Vec<u8, 255>,
8573 }
8574 impl ::emcyphal_encoding::DataType for ExecuteCommandRequest {
8575 const EXTENT_BYTES: Option<u32> = Some(300);
8577 }
8578 impl ::emcyphal_encoding::Request for ExecuteCommandRequest {}
8579 impl ::emcyphal_encoding::BufferType for ExecuteCommandRequest {
8580 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
8581 }
8582 impl ExecuteCommandRequest {
8583 #[cfg_attr(
8584 not(doctest),
8585 doc = " Reboot the node.\n Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset."
8586 )]
8587 pub const COMMAND_RESTART: u16 = 65535;
8588 #[cfg_attr(
8589 not(doctest),
8590 doc = " Shut down the node; further access will not be possible until the power is turned back on."
8591 )]
8592 pub const COMMAND_POWER_OFF: u16 = 65534;
8593 #[cfg_attr(
8594 not(doctest),
8595 doc = " Begin the software update process using uavcan.file.Read. This command makes use of the \"parameter\" field below.\n The parameter contains the path to the new software image file to be downloaded by the server from the client\n using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and\n the server.\n\n Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the\n software update process. If that is deemed impossible, the command will be rejected with one of the\n error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently\n on-duty and a sudden interruption of its activities is considered unsafe, and so on).\n If an update process is already underway, the updatee should abort the process and restart with the new file,\n unless the updatee can determine that the specified file is the same file that is already being downloaded,\n in which case it is allowed to respond SUCCESS and continue the old update process.\n If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and\n initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file\n is transferred fully (please refer to the documentation for that data type for more information about its usage).\n\n While the software is being updated, the updatee should set its mode (the field \"mode\" in uavcan.node.Heartbeat)\n to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.\n\n It is recognized that most systems will have to interrupt their normal services to perform the software update\n (unless some form of software hot swapping is implemented, as is the case in some high-availability systems).\n\n Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware\n and start the embedded bootloader (although other approaches are possible as well). In that case,\n while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be\n MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities\n are currently underway. For example, if the update process failed and the bootloader cannot load the software,\n the same mode MODE_SOFTWARE_UPDATE will be reported.\n It is also recognized that in a microcontroller setting, the application that served the update request will have\n to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to\n the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification."
8596 )]
8597 pub const COMMAND_BEGIN_SOFTWARE_UPDATE: u16 = 65533;
8598 #[cfg_attr(
8599 not(doctest),
8600 doc = " Return the node's configuration back to the factory default settings (may require restart).\n Due to the uncertainty whether a restart is required, generic interfaces should always force a restart."
8601 )]
8602 pub const COMMAND_FACTORY_RESET: u16 = 65532;
8603 #[cfg_attr(
8604 not(doctest),
8605 doc = " Cease activities immediately, enter a safe state until restarted.\n Further operation may no longer be possible until a restart command is executed."
8606 )]
8607 pub const COMMAND_EMERGENCY_STOP: u16 = 65531;
8608 #[cfg_attr(
8609 not(doctest),
8610 doc = " This command instructs the node to store the current configuration parameter values and other persistent states\n to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for\n this command by committing all such data to the non-volatile memory automatically as necessary. However, some\n nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always\n invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic\n persistence management."
8611 )]
8612 pub const COMMAND_STORE_PERSISTENT_STATES: u16 = 65530;
8613 #[cfg_attr(
8614 not(doctest),
8615 doc = " This command instructs the node to physically identify itself in some way--e.g., by flashing a light or\n emitting a sound. The duration and the nature of the identification process is implementation-defined.\n This command can be useful for human operators to match assigned node-ID values to physical nodes during setup."
8616 )]
8617 pub const COMMAND_IDENTIFY: u16 = 65529;
8618 }
8619 impl ::emcyphal_encoding::Serialize for ExecuteCommandRequest {
8620 fn size_bits(&self) -> usize {
8621 16 + 8 + (self.parameter).len() * 8 + 0
8622 }
8623 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8624 cursor.write_aligned_u16(self.command);
8625 cursor.write_aligned_u8((self.parameter).len() as u8);
8626 cursor.write_bytes(&(self.parameter)[..]);
8627 }
8628 }
8629 impl ::emcyphal_encoding::Deserialize for ExecuteCommandRequest {
8630 fn deserialize(
8631 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8632 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8633 where
8634 Self: Sized,
8635 {
8636 Ok(ExecuteCommandRequest {
8637 command: { cursor.read_u16() as _ },
8638 parameter: {
8639 let length = cursor.read_u8() as _;
8640 if length <= 255 {
8641 let mut elements = ::heapless::Vec::new();
8642 for _ in 0..length {
8643 let _ = elements.push(cursor.read_u8() as _);
8644 }
8645 elements
8646 } else {
8647 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8648 }
8649 },
8650 })
8651 }
8652 }
8653
8654 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
8659 #[repr(C, packed)]
8660 #[deprecated]
8661 pub struct ExecuteCommandResponse {
8662 #[cfg_attr(not(doctest), doc = " The result of the request.")]
8663 pub status: u8,
8669 }
8670 impl ::emcyphal_encoding::DataType for ExecuteCommandResponse {
8671 const EXTENT_BYTES: Option<u32> = Some(48);
8673 }
8674 impl ::emcyphal_encoding::Response for ExecuteCommandResponse {}
8675 impl ::emcyphal_encoding::BufferType for ExecuteCommandResponse {
8676 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
8677 }
8678 impl ExecuteCommandResponse {
8679 #[cfg_attr(not(doctest), doc = " Started or executed successfully")]
8680 pub const STATUS_SUCCESS: u8 = 0;
8681 #[cfg_attr(
8682 not(doctest),
8683 doc = " Could not start or the desired outcome could not be reached"
8684 )]
8685 pub const STATUS_FAILURE: u8 = 1;
8686 #[cfg_attr(not(doctest), doc = " Denied due to lack of authorization")]
8687 pub const STATUS_NOT_AUTHORIZED: u8 = 2;
8688 #[cfg_attr(
8689 not(doctest),
8690 doc = " The requested command is not known or not supported"
8691 )]
8692 pub const STATUS_BAD_COMMAND: u8 = 3;
8693 #[cfg_attr(
8694 not(doctest),
8695 doc = " The supplied parameter cannot be used with the selected command"
8696 )]
8697 pub const STATUS_BAD_PARAMETER: u8 = 4;
8698 #[cfg_attr(
8699 not(doctest),
8700 doc = " The current state of the node does not permit execution of this command"
8701 )]
8702 pub const STATUS_BAD_STATE: u8 = 5;
8703 #[cfg_attr(
8704 not(doctest),
8705 doc = " The operation should have succeeded but an unexpected failure occurred"
8706 )]
8707 pub const STATUS_INTERNAL_ERROR: u8 = 6;
8708 }
8709 impl ::emcyphal_encoding::Serialize for ExecuteCommandResponse {
8710 fn size_bits(&self) -> usize {
8711 8
8712 }
8713 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8714 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
8715 }
8716 }
8717 impl ::emcyphal_encoding::Deserialize for ExecuteCommandResponse {
8718 fn deserialize(
8719 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8720 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8721 where
8722 Self: Sized,
8723 {
8724 Ok(Self::deserialize_zero_copy(cursor))
8725 }
8726 }
8727 #[test]
8728 fn test_layout() {
8729 assert_eq!(::core::mem::size_of::<ExecuteCommandResponse>() * 8, 8);
8730 assert_eq!(
8731 ::core::mem::offset_of!(ExecuteCommandResponse, status) * 8,
8732 0
8733 );
8734 }
8735 }
8736 pub mod execute_command_1_3 {
8737 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
8738 pub const SERVICE: ::emcyphal_core::ServiceId =
8739 ::emcyphal_core::ServiceId::from_u16_truncating(435);
8740
8741 #[cfg_attr(
8746 not(doctest),
8747 doc = " Instructs the server node to execute or commence execution of a simple predefined command.\n All standard commands are optional; i.e., not guaranteed to be supported by all nodes."
8748 )]
8749 pub struct ExecuteCommandRequest {
8750 #[cfg_attr(
8751 not(doctest),
8752 doc = " Standard pre-defined commands are at the top of the range (defined below).\n Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).\n Vendor-specific commands shall not use identifiers above 32767."
8753 )]
8754 pub command: u16,
8760 #[cfg_attr(
8761 not(doctest),
8762 doc = " A string parameter supplied to the command. The format and interpretation is command-specific.\n The standard commands do not use this field (ignore it), excepting the following:\n - COMMAND_BEGIN_SOFTWARE_UPDATE"
8763 )]
8764 pub parameter: ::heapless::Vec<u8, 255>,
8770 }
8771 impl ::emcyphal_encoding::DataType for ExecuteCommandRequest {
8772 const EXTENT_BYTES: Option<u32> = Some(300);
8774 }
8775 impl ::emcyphal_encoding::Request for ExecuteCommandRequest {}
8776 impl ::emcyphal_encoding::BufferType for ExecuteCommandRequest {
8777 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
8778 }
8779 impl ExecuteCommandRequest {
8780 #[cfg_attr(
8781 not(doctest),
8782 doc = " Reboot the node.\n Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset."
8783 )]
8784 pub const COMMAND_RESTART: u16 = 65535;
8785 #[cfg_attr(
8786 not(doctest),
8787 doc = " Shut down the node; further access will not be possible until the power is turned back on."
8788 )]
8789 pub const COMMAND_POWER_OFF: u16 = 65534;
8790 #[cfg_attr(
8791 not(doctest),
8792 doc = " Begin the software update process using uavcan.file.Read. This command makes use of the \"parameter\" field below.\n The parameter contains the path to the new software image file to be downloaded by the server from the client\n using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and\n the server.\n\n Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the\n software update process. If that is deemed impossible, the command will be rejected with one of the\n error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently\n on-duty and a sudden interruption of its activities is considered unsafe, and so on).\n If an update process is already underway, the updatee should abort the process and restart with the new file,\n unless the updatee can determine that the specified file is the same file that is already being downloaded,\n in which case it is allowed to respond SUCCESS and continue the old update process.\n If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and\n initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file\n is transferred fully (please refer to the documentation for that data type for more information about its usage).\n\n While the software is being updated, the updatee should set its mode (the field \"mode\" in uavcan.node.Heartbeat)\n to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.\n\n It is recognized that most systems will have to interrupt their normal services to perform the software update\n (unless some form of software hot swapping is implemented, as is the case in some high-availability systems).\n\n Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware\n and start the embedded bootloader (although other approaches are possible as well). In that case,\n while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be\n MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities\n are currently underway. For example, if the update process failed and the bootloader cannot load the software,\n the same mode MODE_SOFTWARE_UPDATE will be reported.\n It is also recognized that in a microcontroller setting, the application that served the update request will have\n to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to\n the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification."
8793 )]
8794 pub const COMMAND_BEGIN_SOFTWARE_UPDATE: u16 = 65533;
8795 #[cfg_attr(
8796 not(doctest),
8797 doc = " Return the node's configuration back to the factory default settings (may require restart).\n Due to the uncertainty whether a restart is required, generic interfaces should always force a restart."
8798 )]
8799 pub const COMMAND_FACTORY_RESET: u16 = 65532;
8800 #[cfg_attr(
8801 not(doctest),
8802 doc = " Cease activities immediately, enter a safe state until restarted.\n Further operation may no longer be possible until a restart command is executed."
8803 )]
8804 pub const COMMAND_EMERGENCY_STOP: u16 = 65531;
8805 #[cfg_attr(
8806 not(doctest),
8807 doc = " This command instructs the node to store the current configuration parameter values and other persistent states\n to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for\n this command by committing all such data to the non-volatile memory automatically as necessary. However, some\n nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always\n invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic\n persistence management."
8808 )]
8809 pub const COMMAND_STORE_PERSISTENT_STATES: u16 = 65530;
8810 #[cfg_attr(
8811 not(doctest),
8812 doc = " This command instructs the node to physically identify itself in some way--e.g., by flashing a light or\n emitting a sound. The duration and the nature of the identification process is implementation-defined.\n This command can be useful for human operators to match assigned node-ID values to physical nodes during setup."
8813 )]
8814 pub const COMMAND_IDENTIFY: u16 = 65529;
8815 }
8816 impl ::emcyphal_encoding::Serialize for ExecuteCommandRequest {
8817 fn size_bits(&self) -> usize {
8818 16 + 8 + (self.parameter).len() * 8 + 0
8819 }
8820 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8821 cursor.write_aligned_u16(self.command);
8822 cursor.write_aligned_u8((self.parameter).len() as u8);
8823 cursor.write_bytes(&(self.parameter)[..]);
8824 }
8825 }
8826 impl ::emcyphal_encoding::Deserialize for ExecuteCommandRequest {
8827 fn deserialize(
8828 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8829 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8830 where
8831 Self: Sized,
8832 {
8833 Ok(ExecuteCommandRequest {
8834 command: { cursor.read_u16() as _ },
8835 parameter: {
8836 let length = cursor.read_u8() as _;
8837 if length <= 255 {
8838 let mut elements = ::heapless::Vec::new();
8839 for _ in 0..length {
8840 let _ = elements.push(cursor.read_u8() as _);
8841 }
8842 elements
8843 } else {
8844 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8845 }
8846 },
8847 })
8848 }
8849 }
8850
8851 pub struct ExecuteCommandResponse {
8856 #[cfg_attr(not(doctest), doc = " The result of the request.")]
8857 pub status: u8,
8863 #[cfg_attr(
8864 not(doctest),
8865 doc = " Any output that could be useful that has the capability to convey detailed information.\n Users can send commands and receive specific data, like device status or measurements back in a streamlined manner.\n The standard commands should leave this field empty unless explicitly specified otherwise."
8866 )]
8867 pub output: ::heapless::Vec<u8, 46>,
8873 }
8874 impl ::emcyphal_encoding::DataType for ExecuteCommandResponse {
8875 const EXTENT_BYTES: Option<u32> = Some(48);
8877 }
8878 impl ::emcyphal_encoding::Response for ExecuteCommandResponse {}
8879 impl ::emcyphal_encoding::BufferType for ExecuteCommandResponse {
8880 type Buffer = ::emcyphal_encoding::StaticBuffer<48>;
8881 }
8882 impl ExecuteCommandResponse {
8883 #[cfg_attr(not(doctest), doc = " Started or executed successfully")]
8884 pub const STATUS_SUCCESS: u8 = 0;
8885 #[cfg_attr(
8886 not(doctest),
8887 doc = " Could not start or the desired outcome could not be reached"
8888 )]
8889 pub const STATUS_FAILURE: u8 = 1;
8890 #[cfg_attr(not(doctest), doc = " Denied due to lack of authorization")]
8891 pub const STATUS_NOT_AUTHORIZED: u8 = 2;
8892 #[cfg_attr(
8893 not(doctest),
8894 doc = " The requested command is not known or not supported"
8895 )]
8896 pub const STATUS_BAD_COMMAND: u8 = 3;
8897 #[cfg_attr(
8898 not(doctest),
8899 doc = " The supplied parameter cannot be used with the selected command"
8900 )]
8901 pub const STATUS_BAD_PARAMETER: u8 = 4;
8902 #[cfg_attr(
8903 not(doctest),
8904 doc = " The current state of the node does not permit execution of this command"
8905 )]
8906 pub const STATUS_BAD_STATE: u8 = 5;
8907 #[cfg_attr(
8908 not(doctest),
8909 doc = " The operation should have succeeded but an unexpected failure occurred"
8910 )]
8911 pub const STATUS_INTERNAL_ERROR: u8 = 6;
8912 }
8913 impl ::emcyphal_encoding::Serialize for ExecuteCommandResponse {
8914 fn size_bits(&self) -> usize {
8915 8 + 8 + (self.output).len() * 8 + 0
8916 }
8917 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8918 cursor.write_aligned_u8(self.status);
8919 cursor.write_aligned_u8((self.output).len() as u8);
8920 cursor.write_bytes(&(self.output)[..]);
8921 }
8922 }
8923 impl ::emcyphal_encoding::Deserialize for ExecuteCommandResponse {
8924 fn deserialize(
8925 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8926 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8927 where
8928 Self: Sized,
8929 {
8930 Ok(ExecuteCommandResponse {
8931 status: { cursor.read_u8() as _ },
8932 output: {
8933 let length = cursor.read_u8() as _;
8934 if length <= 46 {
8935 let mut elements = ::heapless::Vec::new();
8936 for _ in 0..length {
8937 let _ = elements.push(cursor.read_u8() as _);
8938 }
8939 elements
8940 } else {
8941 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
8942 }
8943 },
8944 })
8945 }
8946 }
8947 }
8948 pub mod get_info_1_0 {
8949 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
8950 pub const SERVICE: ::emcyphal_core::ServiceId =
8951 ::emcyphal_core::ServiceId::from_u16_truncating(430);
8952
8953 #[cfg_attr(
8958 not(doctest),
8959 doc = " Full node info request.\n All of the returned information shall be static (unchanged) while the node is running.\n It is highly recommended to support this service on all nodes."
8960 )]
8961 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
8962 #[repr(C, packed)]
8963 pub struct GetInfoRequest {}
8964 impl ::emcyphal_encoding::DataType for GetInfoRequest {
8965 const EXTENT_BYTES: Option<u32> = None;
8967 }
8968 impl ::emcyphal_encoding::Request for GetInfoRequest {}
8969 impl ::emcyphal_encoding::BufferType for GetInfoRequest {
8970 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
8971 }
8972 impl GetInfoRequest {}
8973 impl ::emcyphal_encoding::Serialize for GetInfoRequest {
8974 fn size_bits(&self) -> usize {
8975 0
8976 }
8977 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
8978 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
8979 }
8980 }
8981 impl ::emcyphal_encoding::Deserialize for GetInfoRequest {
8982 fn deserialize(
8983 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
8984 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
8985 where
8986 Self: Sized,
8987 {
8988 Ok(Self::deserialize_zero_copy(cursor))
8989 }
8990 }
8991 #[test]
8992 fn test_layout() {
8993 assert_eq!(::core::mem::size_of::<GetInfoRequest>() * 8, 0);
8994 }
8995
8996 pub struct GetInfoResponse {
9001 #[cfg_attr(
9002 not(doctest),
9003 doc = " The Cyphal protocol version implemented on this node, both major and minor.\n Not to be changed while the node is running."
9004 )]
9005 pub protocol_version: crate::uavcan::node::version_1_0::Version,
9011 pub hardware_version: crate::uavcan::node::version_1_0::Version,
9017 #[cfg_attr(
9018 not(doctest),
9019 doc = " The version information shall not be changed while the node is running.\n The correct hardware version shall be reported at all times, excepting software-only nodes, in which\n case it should be set to zeros.\n If the node is equipped with a Cyphal-capable bootloader, the bootloader should report the software\n version of the installed application, if there is any; if no application is found, zeros should be reported."
9020 )]
9021 pub software_version: crate::uavcan::node::version_1_0::Version,
9027 #[cfg_attr(
9028 not(doctest),
9029 doc = " A version control system (VCS) revision number or hash. Not to be changed while the node is running.\n For example, this field can be used for reporting the short git commit hash of the current\n software revision.\n Set to zero if not used."
9030 )]
9031 pub software_vcs_revision_id: u64,
9037 #[cfg_attr(
9038 not(doctest),
9039 doc = " The unique-ID (UID) is a 128-bit long sequence that is likely to be globally unique per node.\n The vendor shall ensure that the probability of a collision with any other node UID globally is negligibly low.\n UID is defined once per hardware unit and should never be changed.\n All zeros is not a valid UID.\n If the node is equipped with a Cyphal-capable bootloader, the bootloader shall use the same UID.\n Manual serialization note: only fixed-size fields up to this point. The following fields are dynamically sized."
9040 )]
9041 pub unique_id: [u8; 16],
9047 #[cfg_attr(
9048 not(doctest),
9049 doc = " Human-readable non-empty ASCII node name. An empty name is not permitted.\n The name shall not be changed while the node is running.\n Allowed characters are: a-z (lowercase ASCII letters) 0-9 (decimal digits) . (dot) - (dash) _ (underscore).\n Node name is a reversed Internet domain name (like Java packages), e.g. \"com.manufacturer.project.product\"."
9050 )]
9051 pub name: ::heapless::Vec<u8, 50>,
9057 #[cfg_attr(
9058 not(doctest),
9059 doc = " The value of an arbitrary hash function applied to the software image. Not to be changed while the node is running.\n This field can be used to detect whether the software or firmware running on the node is an exact\n same version as a certain specific revision. This field provides a very strong identity guarantee,\n unlike the version fields above, which can be the same for different builds of the software.\n As can be seen from its definition, this field is optional.\n\n The exact hash function and the methods of its application are implementation-defined.\n However, implementations are recommended to adhere to the following guidelines, fully or partially:\n - The hash function should be CRC-64-WE.\n - The hash function should be applied to the entire application image padded to 8 bytes.\n - If the computed image CRC is stored within the software image itself, the value of\n the hash function becomes ill-defined, because it becomes recursively dependent on itself.\n In order to circumvent this issue, while computing or checking the CRC, its value stored\n within the image should be zeroed out."
9060 )]
9061 pub software_image_crc: ::heapless::Vec<u64, 1>,
9067 #[cfg_attr(
9068 not(doctest),
9069 doc = " The certificate of authenticity (COA) of the node, 222 bytes max, optional. This field can be used for\n reporting digital signatures (e.g., RSA-1776, or ECDSA if a higher degree of cryptographic strength is desired).\n Leave empty if not used. Not to be changed while the node is running.\n At most five CAN FD frames"
9070 )]
9071 pub certificate_of_authenticity: ::heapless::Vec<u8, 222>,
9077 }
9078 impl ::emcyphal_encoding::DataType for GetInfoResponse {
9079 const EXTENT_BYTES: Option<u32> = Some(448);
9081 }
9082 impl ::emcyphal_encoding::Response for GetInfoResponse {}
9083 impl ::emcyphal_encoding::BufferType for GetInfoResponse {
9084 type Buffer = ::emcyphal_encoding::StaticBuffer<313>;
9085 }
9086 impl GetInfoResponse {}
9087 impl ::emcyphal_encoding::Serialize for GetInfoResponse {
9088 fn size_bits(&self) -> usize {
9089 16 + 16
9090 + 16
9091 + 64
9092 + (self.unique_id).len() * 8
9093 + 8
9094 + (self.name).len() * 8
9095 + 8
9096 + (self.software_image_crc).len() * 64
9097 + 8
9098 + (self.certificate_of_authenticity).len() * 8
9099 + 0
9100 }
9101 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9102 cursor.write_composite(&self.protocol_version);
9103 cursor.write_composite(&self.hardware_version);
9104 cursor.write_composite(&self.software_version);
9105 cursor.write_aligned_u64(self.software_vcs_revision_id);
9106 cursor.write_bytes(&(self.unique_id)[..]);
9107 cursor.write_aligned_u8((self.name).len() as u8);
9108 cursor.write_bytes(&(self.name)[..]);
9109 cursor.write_aligned_u8((self.software_image_crc).len() as u8);
9110 for value in (self.software_image_crc).iter() {
9111 cursor.write_u64(*value);
9112 }
9113 cursor.write_aligned_u8((self.certificate_of_authenticity).len() as u8);
9114 cursor.write_bytes(&(self.certificate_of_authenticity)[..]);
9115 }
9116 }
9117 impl ::emcyphal_encoding::Deserialize for GetInfoResponse {
9118 fn deserialize(
9119 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9120 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9121 where
9122 Self: Sized,
9123 {
9124 Ok(GetInfoResponse {
9125 protocol_version: { cursor.read_composite()? },
9126 hardware_version: { cursor.read_composite()? },
9127 software_version: { cursor.read_composite()? },
9128 software_vcs_revision_id: { cursor.read_u64() as _ },
9129 unique_id: {
9130 [
9131 cursor.read_u8() as _,
9132 cursor.read_u8() as _,
9133 cursor.read_u8() as _,
9134 cursor.read_u8() as _,
9135 cursor.read_u8() as _,
9136 cursor.read_u8() as _,
9137 cursor.read_u8() as _,
9138 cursor.read_u8() as _,
9139 cursor.read_u8() as _,
9140 cursor.read_u8() as _,
9141 cursor.read_u8() as _,
9142 cursor.read_u8() as _,
9143 cursor.read_u8() as _,
9144 cursor.read_u8() as _,
9145 cursor.read_u8() as _,
9146 cursor.read_u8() as _,
9147 ]
9148 },
9149 name: {
9150 let length = cursor.read_u8() as _;
9151 if length <= 50 {
9152 let mut elements = ::heapless::Vec::new();
9153 for _ in 0..length {
9154 let _ = elements.push(cursor.read_u8() as _);
9155 }
9156 elements
9157 } else {
9158 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
9159 }
9160 },
9161 software_image_crc: {
9162 let length = cursor.read_u8() as _;
9163 if length <= 1 {
9164 let mut elements = ::heapless::Vec::new();
9165 for _ in 0..length {
9166 let _ = elements.push(cursor.read_u64() as _);
9167 }
9168 elements
9169 } else {
9170 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
9171 }
9172 },
9173 certificate_of_authenticity: {
9174 let length = cursor.read_u8() as _;
9175 if length <= 222 {
9176 let mut elements = ::heapless::Vec::new();
9177 for _ in 0..length {
9178 let _ = elements.push(cursor.read_u8() as _);
9179 }
9180 elements
9181 } else {
9182 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
9183 }
9184 },
9185 })
9186 }
9187 }
9188 }
9189 pub mod get_transport_statistics_0_1 {
9190 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
9191 pub const SERVICE: ::emcyphal_core::ServiceId =
9192 ::emcyphal_core::ServiceId::from_u16_truncating(434);
9193
9194 #[cfg_attr(
9199 not(doctest),
9200 doc = " Returns a set of general low-level transport statistical counters.\n Servers are encouraged but not required to sample the data atomically."
9201 )]
9202 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
9203 #[repr(C, packed)]
9204 pub struct GetTransportStatisticsRequest {}
9205 impl ::emcyphal_encoding::DataType for GetTransportStatisticsRequest {
9206 const EXTENT_BYTES: Option<u32> = None;
9208 }
9209 impl ::emcyphal_encoding::Request for GetTransportStatisticsRequest {}
9210 impl ::emcyphal_encoding::BufferType for GetTransportStatisticsRequest {
9211 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
9212 }
9213 impl GetTransportStatisticsRequest {}
9214 impl ::emcyphal_encoding::Serialize for GetTransportStatisticsRequest {
9215 fn size_bits(&self) -> usize {
9216 0
9217 }
9218 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9219 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
9220 }
9221 }
9222 impl ::emcyphal_encoding::Deserialize for GetTransportStatisticsRequest {
9223 fn deserialize(
9224 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9225 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9226 where
9227 Self: Sized,
9228 {
9229 Ok(Self::deserialize_zero_copy(cursor))
9230 }
9231 }
9232 #[test]
9233 fn test_layout() {
9234 assert_eq!(
9235 ::core::mem::size_of::<GetTransportStatisticsRequest>() * 8,
9236 0
9237 );
9238 }
9239
9240 pub struct GetTransportStatisticsResponse {
9245 #[cfg_attr(
9246 not(doctest),
9247 doc = " Cyphal transfer performance statistics:\n the number of Cyphal transfers successfully sent, successfully received, and failed.\n The methods of error counting are implementation-defined."
9248 )]
9249 pub transfer_statistics: crate::uavcan::node::io_statistics_0_1::IOStatistics,
9255 #[cfg_attr(
9256 not(doctest),
9257 doc = " Network interface statistics, separate per interface.\n E.g., for a doubly redundant transport, this array would contain two elements,\n the one at the index zero would apply to the first interface, the other to the second interface.\n The methods of counting are implementation-defined.\n One CAN FD frame"
9258 )]
9259 pub network_interface_statistics:
9265 ::heapless::Vec<crate::uavcan::node::io_statistics_0_1::IOStatistics, 3>,
9266 }
9267 impl ::emcyphal_encoding::DataType for GetTransportStatisticsResponse {
9268 const EXTENT_BYTES: Option<u32> = Some(192);
9270 }
9271 impl ::emcyphal_encoding::Response for GetTransportStatisticsResponse {}
9272 impl ::emcyphal_encoding::BufferType for GetTransportStatisticsResponse {
9273 type Buffer = ::emcyphal_encoding::StaticBuffer<61>;
9274 }
9275 impl GetTransportStatisticsResponse {
9276 #[cfg_attr(
9277 not(doctest),
9278 doc = " Cyphal supports up to triply modular redundant interfaces."
9279 )]
9280 pub const MAX_NETWORK_INTERFACES: u8 = 3;
9281 }
9282 impl ::emcyphal_encoding::Serialize for GetTransportStatisticsResponse {
9283 fn size_bits(&self) -> usize {
9284 120 + 8 + (self.network_interface_statistics).len() * 120 + 0
9285 }
9286 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9287 cursor.write_composite(&self.transfer_statistics);
9288 cursor.write_aligned_u8((self.network_interface_statistics).len() as u8);
9289 for value in (self.network_interface_statistics).iter() {
9290 cursor.write_composite(value);
9291 }
9292 }
9293 }
9294 impl ::emcyphal_encoding::Deserialize for GetTransportStatisticsResponse {
9295 fn deserialize(
9296 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9297 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9298 where
9299 Self: Sized,
9300 {
9301 Ok(GetTransportStatisticsResponse {
9302 transfer_statistics: { cursor.read_composite()? },
9303 network_interface_statistics: {
9304 let length = cursor.read_u8() as _;
9305 if length <= 3 {
9306 let mut elements = ::heapless::Vec::new();
9307 for _ in 0..length {
9308 let _ = elements.push(cursor.read_composite()?);
9309 }
9310 elements
9311 } else {
9312 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
9313 }
9314 },
9315 })
9316 }
9317 }
9318 }
9319 pub mod health_1_0 {
9320 #[cfg_attr(
9325 not(doctest),
9326 doc = " Abstract component health information. If the node performs multiple activities (provides multiple network services),\n its health status should reflect the status of the worst-performing activity (network service).\n Follows:\n https://www.law.cornell.edu/cfr/text/14/23.1322\n https://www.faa.gov/documentLibrary/media/Advisory_Circular/AC_25.1322-1.pdf section 6"
9327 )]
9328 pub struct Health {
9329 pub value: u8,
9335 }
9336 impl ::emcyphal_encoding::DataType for Health {
9337 const EXTENT_BYTES: Option<u32> = None;
9339 }
9340 impl ::emcyphal_encoding::Message for Health {}
9341 impl ::emcyphal_encoding::BufferType for Health {
9342 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
9343 }
9344 impl Health {
9345 #[cfg_attr(
9346 not(doctest),
9347 doc = " The component is functioning properly (nominal)."
9348 )]
9349 pub const NOMINAL: u8 = 0;
9350 #[cfg_attr(
9351 not(doctest),
9352 doc = " A critical parameter went out of range or the component encountered a minor failure that does not prevent\n the subsystem from performing any of its real-time functions."
9353 )]
9354 pub const ADVISORY: u8 = 1;
9355 #[cfg_attr(
9356 not(doctest),
9357 doc = " The component encountered a major failure and is performing in a degraded mode or outside of its designed limitations."
9358 )]
9359 pub const CAUTION: u8 = 2;
9360 #[cfg_attr(
9361 not(doctest),
9362 doc = " The component suffered a fatal malfunction and is unable to perform its intended function."
9363 )]
9364 pub const WARNING: u8 = 3;
9365 }
9366 impl ::emcyphal_encoding::Serialize for Health {
9367 fn size_bits(&self) -> usize {
9368 8
9369 }
9370 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9371 cursor.write_u2(self.value);
9372 }
9373 }
9374 impl ::emcyphal_encoding::Deserialize for Health {
9375 fn deserialize(
9376 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9377 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9378 where
9379 Self: Sized,
9380 {
9381 Ok(Health {
9382 value: { cursor.read_u2() as _ },
9383 })
9384 }
9385 }
9386 }
9387 pub mod heartbeat_1_0 {
9388 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
9389 pub const SUBJECT: ::emcyphal_core::SubjectId =
9390 ::emcyphal_core::SubjectId::from_u16_truncating(7509);
9391
9392 #[cfg_attr(
9397 not(doctest),
9398 doc = " Abstract node status information.\n This is the only high-level function that shall be implemented by all nodes.\n\n All Cyphal nodes that have a node-ID are required to publish this message to its fixed subject periodically.\n Nodes that do not have a node-ID (also known as \"anonymous nodes\") shall not publish to this subject.\n\n The default subject-ID 7509 is 1110101010101 in binary. The alternating bit pattern at the end helps transceiver\n synchronization (e.g., on CAN-based networks) and on some transports permits automatic bit rate detection.\n\n Network-wide health monitoring can be implemented by subscribing to the fixed subject."
9399 )]
9400 pub struct Heartbeat {
9401 #[cfg_attr(
9402 not(doctest),
9403 doc = " [second]\n The uptime seconds counter should never overflow. The counter will reach the upper limit in ~136 years,\n upon which time it should stay at 0xFFFFFFFF until the node is restarted.\n Other nodes may detect that a remote node has restarted when this value leaps backwards."
9404 )]
9405 pub uptime: u32,
9411 #[cfg_attr(not(doctest), doc = " The abstract health status of this node.")]
9412 pub health: crate::uavcan::node::health_1_0::Health,
9418 #[cfg_attr(
9419 not(doctest),
9420 doc = " The abstract operating mode of the publishing node.\n This field indicates the general level of readiness that can be further elaborated on a per-activity basis\n using various specialized interfaces."
9421 )]
9422 pub mode: crate::uavcan::node::mode_1_0::Mode,
9428 #[cfg_attr(
9429 not(doctest),
9430 doc = " Optional, vendor-specific node status code, e.g. a fault code or a status bitmask.\n Fits into a single-frame Classic CAN transfer (least capable transport, smallest MTU)."
9431 )]
9432 pub vendor_specific_status_code: u8,
9438 }
9439 impl ::emcyphal_encoding::DataType for Heartbeat {
9440 const EXTENT_BYTES: Option<u32> = Some(12);
9442 }
9443 impl ::emcyphal_encoding::Message for Heartbeat {}
9444 impl ::emcyphal_encoding::BufferType for Heartbeat {
9445 type Buffer = ::emcyphal_encoding::StaticBuffer<7>;
9446 }
9447 impl Heartbeat {
9448 #[cfg_attr(
9449 not(doctest),
9450 doc = " [second]\n The publication period shall not exceed this limit.\n The period should not change while the node is running."
9451 )]
9452 pub const MAX_PUBLICATION_PERIOD: u16 = 1;
9453 #[cfg_attr(
9454 not(doctest),
9455 doc = " [second]\n If the last message from the node was received more than this amount of time ago, it should be considered offline."
9456 )]
9457 pub const OFFLINE_TIMEOUT: u16 = 3;
9458 }
9459 impl ::emcyphal_encoding::Serialize for Heartbeat {
9460 fn size_bits(&self) -> usize {
9461 56
9462 }
9463 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9464 cursor.write_aligned_u32(self.uptime);
9465 cursor.write_composite(&self.health);
9466 cursor.write_composite(&self.mode);
9467 cursor.write_aligned_u8(self.vendor_specific_status_code);
9468 }
9469 }
9470 impl ::emcyphal_encoding::Deserialize for Heartbeat {
9471 fn deserialize(
9472 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9473 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9474 where
9475 Self: Sized,
9476 {
9477 Ok(Heartbeat {
9478 uptime: { cursor.read_u32() as _ },
9479 health: { cursor.read_composite()? },
9480 mode: { cursor.read_composite()? },
9481 vendor_specific_status_code: { cursor.read_u8() as _ },
9482 })
9483 }
9484 }
9485 }
9486 pub mod id_1_0 {
9487 #[cfg_attr(
9492 not(doctest),
9493 doc = " Defines a node-ID.\n The maximum valid value is dependent on the underlying transport layer.\n Values lower than 128 are always valid for all transports.\n Refer to the specification for more info."
9494 )]
9495 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
9496 #[repr(C, packed)]
9497 pub struct ID {
9498 pub value: u16,
9504 }
9505 impl ::emcyphal_encoding::DataType for ID {
9506 const EXTENT_BYTES: Option<u32> = None;
9508 }
9509 impl ::emcyphal_encoding::Message for ID {}
9510 impl ::emcyphal_encoding::BufferType for ID {
9511 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
9512 }
9513 impl ID {}
9514 impl ::emcyphal_encoding::Serialize for ID {
9515 fn size_bits(&self) -> usize {
9516 16
9517 }
9518 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9519 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
9520 }
9521 }
9522 impl ::emcyphal_encoding::Deserialize for ID {
9523 fn deserialize(
9524 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9525 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9526 where
9527 Self: Sized,
9528 {
9529 Ok(Self::deserialize_zero_copy(cursor))
9530 }
9531 }
9532 #[test]
9533 fn test_layout() {
9534 assert_eq!(::core::mem::size_of::<ID>() * 8, 16);
9535 assert_eq!(::core::mem::offset_of!(ID, value) * 8, 0);
9536 }
9537 }
9538 pub mod io_statistics_0_1 {
9539 #[cfg_attr(
9544 not(doctest),
9545 doc = " A standard set of generic input/output statistical counters that generally should not overflow.\n If a 40-bit counter is incremented every millisecond, it will overflow in ~35 years.\n If an overflow occurs, the value will wrap over to zero.\n\n The values should not be reset while the node is running."
9546 )]
9547 pub struct IOStatistics {
9548 #[cfg_attr(not(doctest), doc = " The number of successfully emitted entities.")]
9549 pub num_emitted: u64,
9555 #[cfg_attr(not(doctest), doc = " The number of successfully received entities.")]
9556 pub num_received: u64,
9562 #[cfg_attr(
9563 not(doctest),
9564 doc = " How many errors have occurred.\n The exact definition of \"error\" and how they are counted are implementation-defined,\n unless specifically defined otherwise."
9565 )]
9566 pub num_errored: u64,
9572 }
9573 impl ::emcyphal_encoding::DataType for IOStatistics {
9574 const EXTENT_BYTES: Option<u32> = None;
9576 }
9577 impl ::emcyphal_encoding::Message for IOStatistics {}
9578 impl ::emcyphal_encoding::BufferType for IOStatistics {
9579 type Buffer = ::emcyphal_encoding::StaticBuffer<15>;
9580 }
9581 impl IOStatistics {}
9582 impl ::emcyphal_encoding::Serialize for IOStatistics {
9583 fn size_bits(&self) -> usize {
9584 120
9585 }
9586 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9587 cursor.write_u40(self.num_emitted);
9588 cursor.write_u40(self.num_received);
9589 cursor.write_u40(self.num_errored);
9590 }
9591 }
9592 impl ::emcyphal_encoding::Deserialize for IOStatistics {
9593 fn deserialize(
9594 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9595 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9596 where
9597 Self: Sized,
9598 {
9599 Ok(IOStatistics {
9600 num_emitted: { cursor.read_u40() as _ },
9601 num_received: { cursor.read_u40() as _ },
9602 num_errored: { cursor.read_u40() as _ },
9603 })
9604 }
9605 }
9606 }
9607 pub mod mode_1_0 {
9608 #[cfg_attr(
9613 not(doctest),
9614 doc = " The operating mode of a node.\n Reserved values can be used in future revisions of the specification."
9615 )]
9616 pub struct Mode {
9617 pub value: u8,
9623 }
9624 impl ::emcyphal_encoding::DataType for Mode {
9625 const EXTENT_BYTES: Option<u32> = None;
9627 }
9628 impl ::emcyphal_encoding::Message for Mode {}
9629 impl ::emcyphal_encoding::BufferType for Mode {
9630 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
9631 }
9632 impl Mode {
9633 #[cfg_attr(not(doctest), doc = " Normal operating mode.")]
9634 pub const OPERATIONAL: u8 = 0;
9635 #[cfg_attr(
9636 not(doctest),
9637 doc = " Initialization is in progress; this mode is entered immediately after startup."
9638 )]
9639 pub const INITIALIZATION: u8 = 1;
9640 #[cfg_attr(not(doctest), doc = " E.g., calibration, self-test, etc.")]
9641 pub const MAINTENANCE: u8 = 2;
9642 #[cfg_attr(
9643 not(doctest),
9644 doc = " New software/firmware is being loaded or the bootloader is running."
9645 )]
9646 pub const SOFTWARE_UPDATE: u8 = 3;
9647 }
9648 impl ::emcyphal_encoding::Serialize for Mode {
9649 fn size_bits(&self) -> usize {
9650 8
9651 }
9652 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9653 cursor.write_u3(self.value);
9654 }
9655 }
9656 impl ::emcyphal_encoding::Deserialize for Mode {
9657 fn deserialize(
9658 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9659 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9660 where
9661 Self: Sized,
9662 {
9663 Ok(Mode {
9664 value: { cursor.read_u3() as _ },
9665 })
9666 }
9667 }
9668 }
9669 pub mod port {
9670 pub mod id_1_0 {
9671 #[cfg_attr(
9676 not(doctest),
9677 doc = " Used to refer either to a Service or to a Subject.\n The chosen tag identifies the kind of the port, then the numerical ID identifies the port within the kind."
9678 )]
9679 pub enum ID {
9680 SubjectId(crate::uavcan::node::port::subject_id_1_0::SubjectID),
9683 ServiceId(crate::uavcan::node::port::service_id_1_0::ServiceID),
9686 }
9687 impl ::emcyphal_encoding::DataType for ID {
9688 const EXTENT_BYTES: Option<u32> = None;
9690 }
9691 impl ::emcyphal_encoding::Message for ID {}
9692 impl ::emcyphal_encoding::BufferType for ID {
9693 type Buffer = ::emcyphal_encoding::StaticBuffer<3>;
9694 }
9695 impl ID {}
9696 impl ::emcyphal_encoding::Serialize for ID {
9697 fn size_bits(&self) -> usize {
9698 24
9699 }
9700 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9701 match self {
9702 ID::SubjectId(inner) => {
9703 cursor.write_aligned_u8(0);
9704 cursor.write_composite(inner);
9705 }
9706 ID::ServiceId(inner) => {
9707 cursor.write_aligned_u8(1);
9708 cursor.write_composite(inner);
9709 }
9710 }
9711 }
9712 }
9713 impl ::emcyphal_encoding::Deserialize for ID {
9714 fn deserialize(
9715 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9716 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9717 where
9718 Self: Sized,
9719 {
9720 match cursor.read_aligned_u8() as _ {
9721 0 => Ok(ID::SubjectId({ cursor.read_composite()? })),
9722 1 => Ok(ID::ServiceId({ cursor.read_composite()? })),
9723 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
9724 }
9725 }
9726 }
9727 }
9728 #[allow(deprecated)]
9729 #[cfg_attr(not(test), deprecated)]
9730 pub mod list_0_1 {
9731 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
9732 #[deprecated]
9733 pub const SUBJECT: ::emcyphal_core::SubjectId =
9734 ::emcyphal_core::SubjectId::from_u16_truncating(7510);
9735
9736 #[cfg_attr(
9741 not(doctest),
9742 doc = " A list of ports that this node is using:\n - Subjects published by this node (whether periodically or ad-hoc).\n - Subjects that this node is subscribed to (a datalogger or a debugger would typically subscribe to all subjects).\n - RPC services consumed by this node (i.e., service clients).\n - RPC services provided by this node (i.e., service servers).\n\n All nodes should implement this capability to provide network introspection and diagnostic capabilities.\n This message should be published using the fixed subject-ID as follows:\n - At the OPTIONAL priority level at least every MAX_PUBLICATION_PERIOD seconds.\n - At the OPTIONAL or SLOW priority level within MAX_PUBLICATION_PERIOD after the port configuration is changed.\n Replaced with v1."
9743 )]
9744 #[deprecated]
9745 pub struct List {
9746 pub publishers: crate::uavcan::node::port::subject_id_list_0_1::SubjectIDList,
9752 pub subscribers: crate::uavcan::node::port::subject_id_list_0_1::SubjectIDList,
9758 pub clients: crate::uavcan::node::port::service_id_list_0_1::ServiceIDList,
9764 pub servers: crate::uavcan::node::port::service_id_list_0_1::ServiceIDList,
9770 }
9771 impl ::emcyphal_encoding::DataType for List {
9772 const EXTENT_BYTES: Option<u32> = None;
9774 }
9775 impl ::emcyphal_encoding::Message for List {}
9776 impl ::emcyphal_encoding::BufferType for List {
9777 type Buffer = ::emcyphal_encoding::StaticBuffer<2194>;
9778 }
9779 impl List {
9780 #[cfg_attr(
9781 not(doctest),
9782 doc = " [seconds]\n If the port configuration is not updated in this amount of time, the node should publish this message anyway."
9783 )]
9784 pub const MAX_PUBLICATION_PERIOD: u8 = 10;
9785 }
9786 impl ::emcyphal_encoding::Serialize for List {
9787 fn size_bits(&self) -> usize {
9788 32 + (self.publishers).size_bits()
9789 + 32
9790 + (self.subscribers).size_bits()
9791 + 32
9792 + 512
9793 + 32
9794 + 512
9795 + 0
9796 }
9797 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9798 cursor.write_composite(&self.publishers);
9799 cursor.write_composite(&self.subscribers);
9800 cursor.write_composite(&self.clients);
9801 cursor.write_composite(&self.servers);
9802 }
9803 }
9804 impl ::emcyphal_encoding::Deserialize for List {
9805 fn deserialize(
9806 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9807 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9808 where
9809 Self: Sized,
9810 {
9811 Ok(List {
9812 publishers: { cursor.read_composite()? },
9813 subscribers: { cursor.read_composite()? },
9814 clients: { cursor.read_composite()? },
9815 servers: { cursor.read_composite()? },
9816 })
9817 }
9818 }
9819 }
9820 pub mod list_1_0 {
9821 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
9822 pub const SUBJECT: ::emcyphal_core::SubjectId =
9823 ::emcyphal_core::SubjectId::from_u16_truncating(7510);
9824
9825 #[cfg_attr(
9830 not(doctest),
9831 doc = " A list of ports that this node is using:\n - Subjects published by this node (whether periodically or ad-hoc).\n - Subjects that this node is subscribed to (a datalogger or a debugger would typically subscribe to all subjects).\n - RPC services consumed by this node (i.e., service clients).\n - RPC services provided by this node (i.e., service servers).\n\n All nodes should implement this capability to provide network introspection and diagnostic capabilities.\n This message should be published using the fixed subject-ID as follows:\n - At the OPTIONAL priority level at least every MAX_PUBLICATION_PERIOD seconds.\n - At the OPTIONAL or SLOW priority level within MAX_PUBLICATION_PERIOD after the port configuration is changed."
9832 )]
9833 pub struct List {
9834 pub publishers: crate::uavcan::node::port::subject_id_list_1_0::SubjectIDList,
9840 pub subscribers: crate::uavcan::node::port::subject_id_list_1_0::SubjectIDList,
9846 pub clients: crate::uavcan::node::port::service_id_list_1_0::ServiceIDList,
9852 pub servers: crate::uavcan::node::port::service_id_list_1_0::ServiceIDList,
9858 }
9859 impl ::emcyphal_encoding::DataType for List {
9860 const EXTENT_BYTES: Option<u32> = None;
9862 }
9863 impl ::emcyphal_encoding::Message for List {}
9864 impl ::emcyphal_encoding::BufferType for List {
9865 type Buffer = ::emcyphal_encoding::StaticBuffer<2194>;
9866 }
9867 impl List {
9868 #[cfg_attr(
9869 not(doctest),
9870 doc = " [seconds]\n If the port configuration is not updated in this amount of time, the node should publish this message anyway."
9871 )]
9872 pub const MAX_PUBLICATION_PERIOD: u8 = 10;
9873 }
9874 impl ::emcyphal_encoding::Serialize for List {
9875 fn size_bits(&self) -> usize {
9876 32 + (self.publishers).size_bits()
9877 + 32
9878 + (self.subscribers).size_bits()
9879 + 32
9880 + 512
9881 + 32
9882 + 512
9883 + 0
9884 }
9885 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9886 cursor.write_composite(&self.publishers);
9887 cursor.write_composite(&self.subscribers);
9888 cursor.write_composite(&self.clients);
9889 cursor.write_composite(&self.servers);
9890 }
9891 }
9892 impl ::emcyphal_encoding::Deserialize for List {
9893 fn deserialize(
9894 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9895 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9896 where
9897 Self: Sized,
9898 {
9899 Ok(List {
9900 publishers: { cursor.read_composite()? },
9901 subscribers: { cursor.read_composite()? },
9902 clients: { cursor.read_composite()? },
9903 servers: { cursor.read_composite()? },
9904 })
9905 }
9906 }
9907 }
9908 pub mod service_id_1_0 {
9909 #[cfg_attr(
9914 not(doctest),
9915 doc = " Service-ID. The ranges are defined by the specification."
9916 )]
9917 pub struct ServiceID {
9918 pub value: u16,
9924 }
9925 impl ::emcyphal_encoding::DataType for ServiceID {
9926 const EXTENT_BYTES: Option<u32> = None;
9928 }
9929 impl ::emcyphal_encoding::Message for ServiceID {}
9930 impl ::emcyphal_encoding::BufferType for ServiceID {
9931 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
9932 }
9933 impl ServiceID {
9934 pub const MAX: u16 = 511;
9935 }
9936 impl ::emcyphal_encoding::Serialize for ServiceID {
9937 fn size_bits(&self) -> usize {
9938 16
9939 }
9940 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9941 cursor.write_u9(self.value);
9942 }
9943 }
9944 impl ::emcyphal_encoding::Deserialize for ServiceID {
9945 fn deserialize(
9946 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
9947 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
9948 where
9949 Self: Sized,
9950 {
9951 Ok(ServiceID {
9952 value: { cursor.read_u9() as _ },
9953 })
9954 }
9955 }
9956 }
9957 #[allow(deprecated)]
9958 #[cfg_attr(not(test), deprecated)]
9959 pub mod service_id_list_0_1 {
9960 #[cfg_attr(
9965 not(doctest),
9966 doc = " A list of service identifiers.\n This is a trivial constant-size bitmask with some reserved space in case the range of service-ID is increased\n in a future revision of the protocol.\n Replaced with v1."
9967 )]
9968 #[deprecated]
9969 pub struct ServiceIDList {
9970 #[cfg_attr(
9971 not(doctest),
9972 doc = " The index represents the identifier value. True -- present/used. False -- absent/unused."
9973 )]
9974 pub mask: ::emcyphal_encoding::bits::BitArray<64>,
9980 }
9981 impl ::emcyphal_encoding::DataType for ServiceIDList {
9982 const EXTENT_BYTES: Option<u32> = Some(128);
9984 }
9985 impl ::emcyphal_encoding::Message for ServiceIDList {}
9986 impl ::emcyphal_encoding::BufferType for ServiceIDList {
9987 type Buffer = ::emcyphal_encoding::StaticBuffer<64>;
9988 }
9989 impl ServiceIDList {
9990 pub const CAPACITY: u16 = 512;
9991 }
9992 impl ::emcyphal_encoding::Serialize for ServiceIDList {
9993 fn size_bits(&self) -> usize {
9994 512
9995 }
9996 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
9997 (self.mask).serialize(cursor);
9998 }
9999 }
10000 impl ::emcyphal_encoding::Deserialize for ServiceIDList {
10001 fn deserialize(
10002 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10003 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10004 where
10005 Self: Sized,
10006 {
10007 Ok(ServiceIDList {
10008 mask: {
10009 ::emcyphal_encoding::bits::BitArray::deserialize(512_usize, cursor)
10010 },
10011 })
10012 }
10013 }
10014 }
10015 pub mod service_id_list_1_0 {
10016 #[cfg_attr(
10021 not(doctest),
10022 doc = " A list of service identifiers.\n This is a trivial constant-size bitmask with some reserved space in case the range of service-ID is increased\n in a future revision of the protocol."
10023 )]
10024 pub struct ServiceIDList {
10025 #[cfg_attr(
10026 not(doctest),
10027 doc = " The index represents the identifier value. True -- present/used. False -- absent/unused."
10028 )]
10029 pub mask: ::emcyphal_encoding::bits::BitArray<64>,
10035 }
10036 impl ::emcyphal_encoding::DataType for ServiceIDList {
10037 const EXTENT_BYTES: Option<u32> = Some(128);
10039 }
10040 impl ::emcyphal_encoding::Message for ServiceIDList {}
10041 impl ::emcyphal_encoding::BufferType for ServiceIDList {
10042 type Buffer = ::emcyphal_encoding::StaticBuffer<64>;
10043 }
10044 impl ServiceIDList {
10045 pub const CAPACITY: u16 = 512;
10046 }
10047 impl ::emcyphal_encoding::Serialize for ServiceIDList {
10048 fn size_bits(&self) -> usize {
10049 512
10050 }
10051 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10052 (self.mask).serialize(cursor);
10053 }
10054 }
10055 impl ::emcyphal_encoding::Deserialize for ServiceIDList {
10056 fn deserialize(
10057 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10058 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10059 where
10060 Self: Sized,
10061 {
10062 Ok(ServiceIDList {
10063 mask: {
10064 ::emcyphal_encoding::bits::BitArray::deserialize(512_usize, cursor)
10065 },
10066 })
10067 }
10068 }
10069 }
10070 pub mod subject_id_1_0 {
10071 #[cfg_attr(
10076 not(doctest),
10077 doc = " Subject-ID. The ranges are defined by the specification."
10078 )]
10079 pub struct SubjectID {
10080 pub value: u16,
10086 }
10087 impl ::emcyphal_encoding::DataType for SubjectID {
10088 const EXTENT_BYTES: Option<u32> = None;
10090 }
10091 impl ::emcyphal_encoding::Message for SubjectID {}
10092 impl ::emcyphal_encoding::BufferType for SubjectID {
10093 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
10094 }
10095 impl SubjectID {
10096 pub const MAX: u16 = 8191;
10097 }
10098 impl ::emcyphal_encoding::Serialize for SubjectID {
10099 fn size_bits(&self) -> usize {
10100 16
10101 }
10102 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10103 cursor.write_u13(self.value);
10104 }
10105 }
10106 impl ::emcyphal_encoding::Deserialize for SubjectID {
10107 fn deserialize(
10108 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10109 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10110 where
10111 Self: Sized,
10112 {
10113 Ok(SubjectID {
10114 value: { cursor.read_u13() as _ },
10115 })
10116 }
10117 }
10118 }
10119 #[allow(deprecated)]
10120 #[cfg_attr(not(test), deprecated)]
10121 pub mod subject_id_list_0_1 {
10122 #[cfg_attr(
10127 not(doctest),
10128 doc = " A list of subject identifiers.\n The range of subject-ID is large, so using a fixed-size bitmask would make this type difficult to handle on\n resource-constrained systems. To address that, we provide two extra options: a simple variable-length list,\n and a special case that indicates that every subject-ID is in use.\n Replaced with v1."
10129 )]
10130 #[deprecated]
10131 pub enum SubjectIDList {
10132 #[cfg_attr(
10133 not(doctest),
10134 doc = " The index represents the identifier value. True -- present/used. False -- absent/unused."
10135 )]
10136 Mask(::emcyphal_encoding::bits::BitArray<1024>),
10139 #[cfg_attr(
10140 not(doctest),
10141 doc = " A list of identifiers that can be used instead of the mask if most of the identifiers are unused."
10142 )]
10143 SparseList(
10146 ::heapless::Vec<crate::uavcan::node::port::subject_id_1_0::SubjectID, 255>,
10147 ),
10148 #[cfg_attr(
10149 not(doctest),
10150 doc = " A special case indicating that all identifiers are in use.\n Reserve space in case the range is extended in the future."
10151 )]
10152 Total(crate::uavcan::primitive::empty_1_0::Empty),
10155 }
10156 impl ::emcyphal_encoding::DataType for SubjectIDList {
10157 const EXTENT_BYTES: Option<u32> = Some(4097);
10159 }
10160 impl ::emcyphal_encoding::Message for SubjectIDList {}
10161 impl ::emcyphal_encoding::BufferType for SubjectIDList {
10162 type Buffer = ::emcyphal_encoding::StaticBuffer<1025>;
10163 }
10164 impl SubjectIDList {
10165 pub const CAPACITY: u16 = 8192;
10166 }
10167 impl ::emcyphal_encoding::Serialize for SubjectIDList {
10168 fn size_bits(&self) -> usize {
10169 8 + match self {
10170 SubjectIDList::Mask(inner) => (inner).len() * 1,
10171 SubjectIDList::SparseList(inner) => 8 + (inner).len() * 16,
10172 SubjectIDList::Total(inner) => 0,
10173 }
10174 }
10175 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10176 match self {
10177 SubjectIDList::Mask(inner) => {
10178 cursor.write_aligned_u8(0);
10179 (*inner).serialize(cursor);
10180 }
10181 SubjectIDList::SparseList(inner) => {
10182 cursor.write_aligned_u8(1);
10183 cursor.write_aligned_u8((*inner).len() as u8);
10184 for value in (*inner).iter() {
10185 cursor.write_composite(value);
10186 }
10187 }
10188 SubjectIDList::Total(inner) => {
10189 cursor.write_aligned_u8(2);
10190 cursor.write_composite(inner);
10191 }
10192 }
10193 }
10194 }
10195 impl ::emcyphal_encoding::Deserialize for SubjectIDList {
10196 fn deserialize(
10197 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10198 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10199 where
10200 Self: Sized,
10201 {
10202 match cursor.read_aligned_u8() as _ {
10203 0 => Ok(SubjectIDList::Mask({
10204 ::emcyphal_encoding::bits::BitArray::deserialize(8192_usize, cursor)
10205 })),
10206 1 => Ok(SubjectIDList::SparseList({
10207 let length = cursor.read_u8() as _;
10208 if length <= 255 {
10209 let mut elements = ::heapless::Vec::new();
10210 for _ in 0..length {
10211 let _ = elements.push(cursor.read_composite()?);
10212 }
10213 elements
10214 } else {
10215 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
10216 }
10217 })),
10218 2 => Ok(SubjectIDList::Total({ cursor.read_composite()? })),
10219 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
10220 }
10221 }
10222 }
10223 }
10224 pub mod subject_id_list_1_0 {
10225 #[cfg_attr(
10230 not(doctest),
10231 doc = " A list of subject identifiers.\n The range of subject-ID is large, so using a fixed-size bitmask would make this type difficult to handle on\n resource-constrained systems. To address that, we provide two extra options: a simple variable-length list,\n and a special case that indicates that every subject-ID is in use."
10232 )]
10233 pub enum SubjectIDList {
10234 #[cfg_attr(
10235 not(doctest),
10236 doc = " The index represents the identifier value. True -- present/used. False -- absent/unused."
10237 )]
10238 Mask(::emcyphal_encoding::bits::BitArray<1024>),
10241 #[cfg_attr(
10242 not(doctest),
10243 doc = " A list of identifiers that can be used instead of the mask if most of the identifiers are unused."
10244 )]
10245 SparseList(
10248 ::heapless::Vec<crate::uavcan::node::port::subject_id_1_0::SubjectID, 255>,
10249 ),
10250 #[cfg_attr(
10251 not(doctest),
10252 doc = " A special case indicating that all identifiers are in use.\n Reserve space in case the range is extended in the future."
10253 )]
10254 Total(crate::uavcan::primitive::empty_1_0::Empty),
10257 }
10258 impl ::emcyphal_encoding::DataType for SubjectIDList {
10259 const EXTENT_BYTES: Option<u32> = Some(4097);
10261 }
10262 impl ::emcyphal_encoding::Message for SubjectIDList {}
10263 impl ::emcyphal_encoding::BufferType for SubjectIDList {
10264 type Buffer = ::emcyphal_encoding::StaticBuffer<1025>;
10265 }
10266 impl SubjectIDList {
10267 pub const CAPACITY: u16 = 8192;
10268 }
10269 impl ::emcyphal_encoding::Serialize for SubjectIDList {
10270 fn size_bits(&self) -> usize {
10271 8 + match self {
10272 SubjectIDList::Mask(inner) => (inner).len() * 1,
10273 SubjectIDList::SparseList(inner) => 8 + (inner).len() * 16,
10274 SubjectIDList::Total(inner) => 0,
10275 }
10276 }
10277 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10278 match self {
10279 SubjectIDList::Mask(inner) => {
10280 cursor.write_aligned_u8(0);
10281 (*inner).serialize(cursor);
10282 }
10283 SubjectIDList::SparseList(inner) => {
10284 cursor.write_aligned_u8(1);
10285 cursor.write_aligned_u8((*inner).len() as u8);
10286 for value in (*inner).iter() {
10287 cursor.write_composite(value);
10288 }
10289 }
10290 SubjectIDList::Total(inner) => {
10291 cursor.write_aligned_u8(2);
10292 cursor.write_composite(inner);
10293 }
10294 }
10295 }
10296 }
10297 impl ::emcyphal_encoding::Deserialize for SubjectIDList {
10298 fn deserialize(
10299 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10300 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10301 where
10302 Self: Sized,
10303 {
10304 match cursor.read_aligned_u8() as _ {
10305 0 => Ok(SubjectIDList::Mask({
10306 ::emcyphal_encoding::bits::BitArray::deserialize(8192_usize, cursor)
10307 })),
10308 1 => Ok(SubjectIDList::SparseList({
10309 let length = cursor.read_u8() as _;
10310 if length <= 255 {
10311 let mut elements = ::heapless::Vec::new();
10312 for _ in 0..length {
10313 let _ = elements.push(cursor.read_composite()?);
10314 }
10315 elements
10316 } else {
10317 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
10318 }
10319 })),
10320 2 => Ok(SubjectIDList::Total({ cursor.read_composite()? })),
10321 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
10322 }
10323 }
10324 }
10325 }
10326 }
10327 pub mod version_1_0 {
10328 #[cfg_attr(
10333 not(doctest),
10334 doc = " A shortened semantic version representation: only major and minor.\n The protocol generally does not concern itself with the patch version."
10335 )]
10336 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
10337 #[repr(C, packed)]
10338 pub struct Version {
10339 pub major: u8,
10345 pub minor: u8,
10351 }
10352 impl ::emcyphal_encoding::DataType for Version {
10353 const EXTENT_BYTES: Option<u32> = None;
10355 }
10356 impl ::emcyphal_encoding::Message for Version {}
10357 impl ::emcyphal_encoding::BufferType for Version {
10358 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
10359 }
10360 impl Version {}
10361 impl ::emcyphal_encoding::Serialize for Version {
10362 fn size_bits(&self) -> usize {
10363 16
10364 }
10365 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10366 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
10367 }
10368 }
10369 impl ::emcyphal_encoding::Deserialize for Version {
10370 fn deserialize(
10371 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10372 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10373 where
10374 Self: Sized,
10375 {
10376 Ok(Self::deserialize_zero_copy(cursor))
10377 }
10378 }
10379 #[test]
10380 fn test_layout() {
10381 assert_eq!(::core::mem::size_of::<Version>() * 8, 16);
10382 assert_eq!(::core::mem::offset_of!(Version, major) * 8, 0);
10383 assert_eq!(::core::mem::offset_of!(Version, minor) * 8, 8);
10384 }
10385 }
10386 }
10387 pub mod pnp {
10388 pub mod cluster {
10389 pub mod append_entries_1_0 {
10390 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
10391 pub const SERVICE: ::emcyphal_core::ServiceId =
10392 ::emcyphal_core::ServiceId::from_u16_truncating(390);
10393
10394 #[cfg_attr(
10399 not(doctest),
10400 doc = " This type is a part of the Raft consensus algorithm. The Raft consensus is used for the maintenance of the\n distributed allocation table between redundant allocators. The following description is focused on the exchanges\n between redundant PnP node-ID allocators. It does not apply to the case of non-redundant allocators, because\n in that case the allocation table is stored locally and the process of node-ID allocation is trivial and fully local.\n Exchanges between allocatees and allocators are documented in the appropriate message type definition.\n\n The algorithm used for replication of the allocation table across redundant allocators is a fairly direct\n implementation of the Raft consensus algorithm, as published in the paper\n \"In Search of an Understandable Consensus Algorithm (Extended Version)\" by Diego Ongaro and John Ousterhout.\n The following text assumes that the reader is familiar with the paper.\n\n The Raft log contains entries of type Entry (in the same namespace), where every entry contains the Raft term\n number, the unique-ID, and the corresponding node-ID value (or zeros if it could not be requested from a static\n node). Therefore, the Raft log is the allocation table itself.\n\n Since the maximum number of entries in the allocation table is limited by the range of node-ID values, the log\n capacity is bounded. Therefore, the snapshot transfer and log compaction functions are not required,\n so they are not used in this implementation of the Raft algorithm.\n\n When an allocator becomes the leader of the Raft cluster, it checks if the Raft log contains an entry for its own\n node-ID, and if it doesn't, the leader adds its own allocation entry to the log (the unique-ID can be replaced with\n zeros at the discretion of the implementer). This behavior guarantees that the Raft log always contains at least\n one entry, therefore it is not necessary to support negative log indices, as proposed by the Raft paper.\n\n Since the log is write-only and limited in growth, all allocations are permanent. This restriction is acceptable,\n since Cyphal is a vehicle bus, and configuration of vehicle's components is not expected to change frequently.\n Old allocations can be removed in order to free node-IDs for new allocations by clearing the Raft log on all\n allocators; such clearing shall be performed simultaneously while the network is down, otherwise the Raft cluster\n will automatically attempt to restore the lost state on the allocators where the table was cleared.\n\n The allocators need to be aware of each other's node-ID in order to form a cluster. In order to learn each other's\n node-ID values, the allocators broadcast messages of type Discovery (in the same namespace) until the cluster is\n fully discovered and all allocators know of each other's node-ID. This extension to the Raft algorithm makes the\n cluster almost configuration-free - the only parameter that shall be configured on all allocators of the cluster\n is the number of nodes in the cluster (everything else will be auto-detected).\n\n Runtime cluster membership changes are not supported, since they are not needed for a vehicle bus.\n\n As has been explained in the general description of the PnP node-ID allocation feature, allocators shall watch for\n unknown static nodes appearing on the bus. In the case of a non-redundant allocator, the task is trivial, since the\n allocation table can be updated locally. In the case of a Raft cluster, however, the network monitoring task shall\n be performed by the leader only, since other cluster members cannot commit to the shared allocation table (i.e.,\n the Raft log) anyway. Redundant allocators should not attempt to obtain the true unique-ID of the newly detected\n static nodes (use zeros instead), because the allocation table is write-only: if the unique-ID of a static node\n ever changes (e.g., a replacement unit is installed, or network configuration is changed manually), the change\n will be impossible to reflect in the allocation table.\n\n Only the current Raft leader can process allocation requests and engage in communication with allocatees.\n An allocator is allowed to send allocation responses only if both conditions are met:\n\n - The allocator is currently the Raft leader.\n - Its replica of the Raft log does not contain uncommitted entries (i.e. the last allocation request has been\n completed successfully).\n\n All cluster maintenance traffic should normally use either the lowest or the next-to-lowest transfer priority level."
10401 )]
10402 pub struct AppendEntriesRequest {
10403 pub term: u32,
10409 pub prev_log_term: u32,
10415 pub prev_log_index: u16,
10421 #[cfg_attr(not(doctest), doc = " Refer to the Raft paper for explanation.")]
10422 pub leader_commit: u16,
10428 #[cfg_attr(
10429 not(doctest),
10430 doc = " Worst case replication time per Follower can be computed as:\n\n worst replication time = (node-ID capacity) * (2 trips of next_index) * (request interval per Follower)\n\n E.g., given the request interval of 0.5 seconds, the worst case replication time for CAN bus is:\n\n 128 nodes * 2 trips * 0.5 seconds = 128 seconds.\n\n This is the amount of time it will take for a new Follower to reconstruct a full replica of the distributed log."
10431 )]
10432 pub entries: ::heapless::Vec<crate::uavcan::pnp::cluster::entry_1_0::Entry, 1>,
10438 }
10439 impl ::emcyphal_encoding::DataType for AppendEntriesRequest {
10440 const EXTENT_BYTES: Option<u32> = Some(96);
10442 }
10443 impl ::emcyphal_encoding::Request for AppendEntriesRequest {}
10444 impl ::emcyphal_encoding::BufferType for AppendEntriesRequest {
10445 type Buffer = ::emcyphal_encoding::StaticBuffer<35>;
10446 }
10447 impl AppendEntriesRequest {
10448 #[cfg_attr(not(doctest), doc = " [second]")]
10449 pub const DEFAULT_MIN_ELECTION_TIMEOUT: u8 = 2;
10450 #[cfg_attr(
10451 not(doctest),
10452 doc = " [second]\n Given the minimum election timeout and the cluster size,\n the maximum recommended request interval can be derived as follows:\n\n max recommended request interval = (min election timeout) / 2 requests / (cluster size - 1)\n\n The equation assumes that the Leader requests one Follower at a time, so that there's at most one pending call\n at any moment. Such behavior is optimal as it creates a uniform bus load, although it is implementation-specific.\n Obviously, the request interval can be lower than that if needed, but higher values are not recommended as they may\n cause Followers to initiate premature elections in case of frame losses or delays.\n\n The timeout value is randomized in the range (MIN, MAX], according to the Raft paper. The randomization granularity\n should be at least one millisecond or higher."
10453 )]
10454 pub const DEFAULT_MAX_ELECTION_TIMEOUT: u8 = 4;
10455 }
10456 impl ::emcyphal_encoding::Serialize for AppendEntriesRequest {
10457 fn size_bits(&self) -> usize {
10458 32 + 32 + 16 + 16 + 8 + (self.entries).len() * 176 + 0
10459 }
10460 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10461 cursor.write_aligned_u32(self.term);
10462 cursor.write_aligned_u32(self.prev_log_term);
10463 cursor.write_aligned_u16(self.prev_log_index);
10464 cursor.write_aligned_u16(self.leader_commit);
10465 cursor.write_aligned_u8((self.entries).len() as u8);
10466 for value in (self.entries).iter() {
10467 cursor.write_composite(value);
10468 }
10469 }
10470 }
10471 impl ::emcyphal_encoding::Deserialize for AppendEntriesRequest {
10472 fn deserialize(
10473 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10474 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10475 where
10476 Self: Sized,
10477 {
10478 Ok(AppendEntriesRequest {
10479 term: { cursor.read_u32() as _ },
10480 prev_log_term: { cursor.read_u32() as _ },
10481 prev_log_index: { cursor.read_u16() as _ },
10482 leader_commit: { cursor.read_u16() as _ },
10483 entries: {
10484 let length = cursor.read_u8() as _;
10485 if length <= 1 {
10486 let mut elements = ::heapless::Vec::new();
10487 for _ in 0..length {
10488 let _ = elements.push(cursor.read_composite()?);
10489 }
10490 elements
10491 } else {
10492 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
10493 }
10494 },
10495 })
10496 }
10497 }
10498
10499 pub struct AppendEntriesResponse {
10504 pub term: u32,
10510 #[cfg_attr(not(doctest), doc = " Refer to the Raft paper for explanation.")]
10511 pub success: bool,
10517 }
10518 impl ::emcyphal_encoding::DataType for AppendEntriesResponse {
10519 const EXTENT_BYTES: Option<u32> = Some(48);
10521 }
10522 impl ::emcyphal_encoding::Response for AppendEntriesResponse {}
10523 impl ::emcyphal_encoding::BufferType for AppendEntriesResponse {
10524 type Buffer = ::emcyphal_encoding::StaticBuffer<5>;
10525 }
10526 impl AppendEntriesResponse {}
10527 impl ::emcyphal_encoding::Serialize for AppendEntriesResponse {
10528 fn size_bits(&self) -> usize {
10529 40
10530 }
10531 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10532 cursor.write_aligned_u32(self.term);
10533 cursor.write_bool(self.success);
10534 }
10535 }
10536 impl ::emcyphal_encoding::Deserialize for AppendEntriesResponse {
10537 fn deserialize(
10538 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10539 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10540 where
10541 Self: Sized,
10542 {
10543 Ok(AppendEntriesResponse {
10544 term: { cursor.read_u32() as _ },
10545 success: { cursor.read_bool() },
10546 })
10547 }
10548 }
10549 }
10550 pub mod discovery_1_0 {
10551 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
10552 pub const SUBJECT: ::emcyphal_core::SubjectId =
10553 ::emcyphal_core::SubjectId::from_u16_truncating(8164);
10554
10555 #[cfg_attr(
10560 not(doctest),
10561 doc = " This message is used by redundant allocators to find each other's node-ID.\n Please refer to the type AppendEntries for details.\n\n An allocator should stop publishing this message as soon as it has discovered all other allocators in the cluster.\n\n An exception applies: when an allocator receives a Discovery message where the list of known nodes is incomplete\n (i.e. len(known_nodes) < configured_cluster_size), it shall publish a Discovery message once. This condition\n allows other allocators to quickly re-discover the cluster after a restart."
10562 )]
10563 pub struct Discovery {
10564 #[cfg_attr(
10565 not(doctest),
10566 doc = " The number of allocators in the cluster as configured on the sender.\n This value shall be the same across all allocators."
10567 )]
10568 pub configured_cluster_size: u8,
10574 #[cfg_attr(
10576 not(doctest),
10577 doc = " Node-IDs of the allocators that are known to the publishing allocator, including the publishing allocator itself."
10578 )]
10579 pub known_nodes: ::heapless::Vec<crate::uavcan::node::id_1_0::ID, 5>,
10585 }
10586 impl ::emcyphal_encoding::DataType for Discovery {
10587 const EXTENT_BYTES: Option<u32> = Some(96);
10589 }
10590 impl ::emcyphal_encoding::Message for Discovery {}
10591 impl ::emcyphal_encoding::BufferType for Discovery {
10592 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
10593 }
10594 impl Discovery {
10595 #[cfg_attr(
10596 not(doctest),
10597 doc = " [second]\n This message should be broadcasted by the allocator at this interval until all other allocators are discovered."
10598 )]
10599 pub const BROADCASTING_PERIOD: u8 = 1;
10600 #[cfg_attr(
10601 not(doctest),
10602 doc = " The redundant allocator cluster cannot contain more than 5 allocators."
10603 )]
10604 pub const MAX_CLUSTER_SIZE: u8 = 5;
10605 }
10606 impl ::emcyphal_encoding::Serialize for Discovery {
10607 fn size_bits(&self) -> usize {
10608 3 + 5 + 8 + (self.known_nodes).len() * 16 + 0
10609 }
10610 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10611 cursor.write_u3(self.configured_cluster_size);
10612 cursor.skip_5();
10613 cursor.write_aligned_u8((self.known_nodes).len() as u8);
10614 for value in (self.known_nodes).iter() {
10615 cursor.write_composite(value);
10616 }
10617 }
10618 }
10619 impl ::emcyphal_encoding::Deserialize for Discovery {
10620 fn deserialize(
10621 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10622 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10623 where
10624 Self: Sized,
10625 {
10626 Ok(Discovery {
10627 configured_cluster_size: { cursor.read_u3() as _ },
10628 known_nodes: {
10629 cursor.skip_5();
10630 let length = cursor.read_u8() as _;
10631 if length <= 5 {
10632 let mut elements = ::heapless::Vec::new();
10633 for _ in 0..length {
10634 let _ = elements.push(cursor.read_composite()?);
10635 }
10636 elements
10637 } else {
10638 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
10639 }
10640 },
10641 })
10642 }
10643 }
10644 }
10645 pub mod entry_1_0 {
10646 #[cfg_attr(
10651 not(doctest),
10652 doc = " One PnP node-ID allocation entry.\n This type is a part of the Raft consensus algorithm. Please refer to the type AppendEntries for details."
10653 )]
10654 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
10655 #[repr(C, packed)]
10656 pub struct Entry {
10657 #[cfg_attr(not(doctest), doc = " Refer to the Raft paper for explanation.")]
10658 pub term: u32,
10664 #[cfg_attr(
10665 not(doctest),
10666 doc = " Unique-ID of this allocation; zero if unknown."
10667 )]
10668 pub unique_id: [u8; 16],
10674 #[cfg_attr(not(doctest), doc = " Node-ID of this allocation.")]
10675 pub node_id: crate::uavcan::node::id_1_0::ID,
10681 }
10682 impl ::emcyphal_encoding::DataType for Entry {
10683 const EXTENT_BYTES: Option<u32> = None;
10685 }
10686 impl ::emcyphal_encoding::Message for Entry {}
10687 impl ::emcyphal_encoding::BufferType for Entry {
10688 type Buffer = ::emcyphal_encoding::StaticBuffer<22>;
10689 }
10690 impl Entry {}
10691 impl ::emcyphal_encoding::Serialize for Entry {
10692 fn size_bits(&self) -> usize {
10693 176
10694 }
10695 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10696 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
10697 }
10698 }
10699 impl ::emcyphal_encoding::Deserialize for Entry {
10700 fn deserialize(
10701 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10702 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10703 where
10704 Self: Sized,
10705 {
10706 Ok(Self::deserialize_zero_copy(cursor))
10707 }
10708 }
10709 #[test]
10710 fn test_layout() {
10711 assert_eq!(::core::mem::size_of::<Entry>() * 8, 176);
10712 assert_eq!(::core::mem::offset_of!(Entry, term) * 8, 0);
10713 assert_eq!(::core::mem::offset_of!(Entry, unique_id) * 8, 32);
10714 assert_eq!(::core::mem::offset_of!(Entry, node_id) * 8, 160);
10715 }
10716 }
10717 pub mod request_vote_1_0 {
10718 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
10719 pub const SERVICE: ::emcyphal_core::ServiceId =
10720 ::emcyphal_core::ServiceId::from_u16_truncating(391);
10721
10722 #[cfg_attr(
10727 not(doctest),
10728 doc = " This type is a part of the Raft consensus algorithm. Please refer to the type AppendEntries for details."
10729 )]
10730 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
10731 #[repr(C, packed)]
10732 pub struct RequestVoteRequest {
10733 pub term: u32,
10739 pub last_log_term: u32,
10745 #[cfg_attr(not(doctest), doc = " Refer to the Raft paper for explanation.")]
10746 pub last_log_index: u16,
10752 }
10753 impl ::emcyphal_encoding::DataType for RequestVoteRequest {
10754 const EXTENT_BYTES: Option<u32> = Some(48);
10756 }
10757 impl ::emcyphal_encoding::Request for RequestVoteRequest {}
10758 impl ::emcyphal_encoding::BufferType for RequestVoteRequest {
10759 type Buffer = ::emcyphal_encoding::StaticBuffer<10>;
10760 }
10761 impl RequestVoteRequest {}
10762 impl ::emcyphal_encoding::Serialize for RequestVoteRequest {
10763 fn size_bits(&self) -> usize {
10764 80
10765 }
10766 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10767 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
10768 }
10769 }
10770 impl ::emcyphal_encoding::Deserialize for RequestVoteRequest {
10771 fn deserialize(
10772 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10773 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10774 where
10775 Self: Sized,
10776 {
10777 Ok(Self::deserialize_zero_copy(cursor))
10778 }
10779 }
10780 #[test]
10781 fn test_layout() {
10782 assert_eq!(::core::mem::size_of::<RequestVoteRequest>() * 8, 80);
10783 assert_eq!(::core::mem::offset_of!(RequestVoteRequest, term) * 8, 0);
10784 assert_eq!(
10785 ::core::mem::offset_of!(RequestVoteRequest, last_log_term) * 8,
10786 32
10787 );
10788 assert_eq!(
10789 ::core::mem::offset_of!(RequestVoteRequest, last_log_index) * 8,
10790 64
10791 );
10792 }
10793
10794 pub struct RequestVoteResponse {
10799 pub term: u32,
10805 #[cfg_attr(not(doctest), doc = " Refer to the Raft paper for explanation.")]
10806 pub vote_granted: bool,
10812 }
10813 impl ::emcyphal_encoding::DataType for RequestVoteResponse {
10814 const EXTENT_BYTES: Option<u32> = Some(48);
10816 }
10817 impl ::emcyphal_encoding::Response for RequestVoteResponse {}
10818 impl ::emcyphal_encoding::BufferType for RequestVoteResponse {
10819 type Buffer = ::emcyphal_encoding::StaticBuffer<5>;
10820 }
10821 impl RequestVoteResponse {}
10822 impl ::emcyphal_encoding::Serialize for RequestVoteResponse {
10823 fn size_bits(&self) -> usize {
10824 40
10825 }
10826 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10827 cursor.write_aligned_u32(self.term);
10828 cursor.write_bool(self.vote_granted);
10829 }
10830 }
10831 impl ::emcyphal_encoding::Deserialize for RequestVoteResponse {
10832 fn deserialize(
10833 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10834 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10835 where
10836 Self: Sized,
10837 {
10838 Ok(RequestVoteResponse {
10839 term: { cursor.read_u32() as _ },
10840 vote_granted: { cursor.read_bool() },
10841 })
10842 }
10843 }
10844 }
10845 }
10846 pub mod node_id_allocation_data_1_0 {
10847 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
10848 pub const SUBJECT: ::emcyphal_core::SubjectId =
10849 ::emcyphal_core::SubjectId::from_u16_truncating(8166);
10850
10851 #[cfg_attr(
10856 not(doctest),
10857 doc = " This definition of the allocation message is intended for use with transports where anonymous transfers are limited\n to 7 bytes of payload, such as Classic CAN. The definition is carried over from the original UAVCAN v0 specification\n with some modifications. For transports other than Classic CAN (e.g., CAN FD, serial, etc.) there is a more\n general, more capable definition NodeIDAllocationData v2.0. The PnP protocol itself is described in the documentation\n for the v2 definition. The documentation provided here builds upon the general case, so read that first please.\n\n The full 128-bit unique-ID can't be accommodated in a single-frame anonymous message transfer over Classic CAN, so\n this definition substitutes the full 128-bit ID with a smaller 48-bit hash of it. The 48-bit hash is obtained by\n applying an arbitrary hash function to the unique-ID that outputs at least 48 bit of data. The recommended hash\n function is the standard CRC-64WE where only the lowest 48 bit of the result are used.\n\n Allocators that support allocation messages of different versions should maintain a shared allocation table for all.\n Requests received via the v1 message obviously do not contain the full unique-ID; the allocators are recommended\n to left-zero-pad the small 48-bit hash in order to obtain a \"pseudo unique-ID\", and use this value in the\n allocation table as a substitute for the real unique-ID. It is recognized that this behavior will have certain\n side effects, such as the same allocatee obtaining different allocated node-ID values depending on which version\n of the message is used, but they are considered tolerable.\n\n Allocatees that may need to operate over Classic CAN along with high-MTU transports may choose to use\n only this constrained method of allocation for consistency and simplification.\n\n In order to save space for the hash, the preferred node-ID is removed from the request. The allocated node-ID\n is provided in the response, however; this is achieved by means of an optional field that is not populated in\n the request but is populated in the response. This implies that the response may be a multi-frame transfer,\n which is acceptable since responses are sent by allocators, which are regular nodes, and therefore they are\n allowed to use regular message transfers rather than being limited to anonymous message transfers as allocatees are.\n\n On the allocatee's side the protocol is defined through the following set of rules:\n\n Rule A. On initialization:\n 1. The allocatee subscribes to this message.\n 2. The allocatee starts the Request Timer with a random interval of Trequest.\n\n Rule B. On expiration of the Request Timer (started as per rules A, B, or C):\n 1. Request Timer restarts with a random interval of Trequest (chosen anew).\n 2. The allocatee broadcasts an allocation request message, where the fields are populated as follows:\n unique_id_hash - a 48-bit hash of the unique-ID of the allocatee.\n allocated_node_id - empty (not populated).\n\n Rule C. On any allocation message, even if other rules also match:\n 1. Request Timer restarts with a random interval of Trequest (chosen anew).\n\n Rule D. On an allocation message WHERE (source node-ID is non-anonymous, i.e., regular allocation response)\n AND (the field unique_id_hash matches the allocatee's 48-bit unique-ID hash)\n AND (the field allocated_node_id is populated):\n 1. Request Timer stops.\n 2. The allocatee initializes its node-ID with the received value.\n 3. The allocatee terminates its subscription to allocation messages.\n 4. Exit."
10858 )]
10859 pub struct NodeIDAllocationData {
10860 #[cfg_attr(
10861 not(doctest),
10862 doc = " An arbitrary 48-bit hash of the unique-ID of the local node."
10863 )]
10864 pub unique_id_hash: u64,
10870 #[cfg_attr(
10871 not(doctest),
10872 doc = " Shall be empty in request messages.\n Shall be populated in response messages."
10873 )]
10874 pub allocated_node_id: ::heapless::Vec<crate::uavcan::node::id_1_0::ID, 1>,
10880 }
10881 impl ::emcyphal_encoding::DataType for NodeIDAllocationData {
10882 const EXTENT_BYTES: Option<u32> = None;
10884 }
10885 impl ::emcyphal_encoding::Message for NodeIDAllocationData {}
10886 impl ::emcyphal_encoding::BufferType for NodeIDAllocationData {
10887 type Buffer = ::emcyphal_encoding::StaticBuffer<9>;
10888 }
10889 impl NodeIDAllocationData {}
10890 impl ::emcyphal_encoding::Serialize for NodeIDAllocationData {
10891 fn size_bits(&self) -> usize {
10892 48 + 8 + (self.allocated_node_id).len() * 16 + 0
10893 }
10894 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10895 cursor.write_u48(self.unique_id_hash);
10896 cursor.write_aligned_u8((self.allocated_node_id).len() as u8);
10897 for value in (self.allocated_node_id).iter() {
10898 cursor.write_composite(value);
10899 }
10900 }
10901 }
10902 impl ::emcyphal_encoding::Deserialize for NodeIDAllocationData {
10903 fn deserialize(
10904 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10905 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10906 where
10907 Self: Sized,
10908 {
10909 Ok(NodeIDAllocationData {
10910 unique_id_hash: { cursor.read_u48() as _ },
10911 allocated_node_id: {
10912 let length = cursor.read_u8() as _;
10913 if length <= 1 {
10914 let mut elements = ::heapless::Vec::new();
10915 for _ in 0..length {
10916 let _ = elements.push(cursor.read_composite()?);
10917 }
10918 elements
10919 } else {
10920 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
10921 }
10922 },
10923 })
10924 }
10925 }
10926 }
10927 pub mod node_id_allocation_data_2_0 {
10928 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
10929 pub const SUBJECT: ::emcyphal_core::SubjectId =
10930 ::emcyphal_core::SubjectId::from_u16_truncating(8165);
10931
10932 #[cfg_attr(
10937 not(doctest),
10938 doc = " In order to be able to operate in a Cyphal network, a node shall have a node-ID that is unique within the network.\n Typically, a valid node-ID can be configured manually for each node; however, in certain use cases the manual\n approach is either undesirable or impossible, therefore Cyphal defines the high-level feature of plug-and-play\n nodes that allows nodes to obtain a node-ID value automatically upon connection to the network. When combined\n with automatic physical layer configuration (such as auto bit rate detection), this feature allows one to implement\n nodes that can join a Cyphal network without any prior manual configuration whatsoever. Such nodes are referred to\n as \"plug-and-play nodes\" (or \"PnP nodes\" for brevity).\n\n The feature is fundamentally non-deterministic and is likely to be unfit for some high-reliability systems;\n the designers need to carefully consider the trade-offs involved before deciding to rely on this feature.\n Normally, static node-ID settings should be preferred.\n\n This feature relies on the concept of \"anonymous message transfers\", please consult with the Cyphal transport\n layer specification for details.\n\n The process of plug-and-play node-ID allocation always involves two types of nodes: \"allocators\", which serve\n allocation requests; and \"allocatees\", which request PnP node-ID from allocators. A Cyphal network may implement\n the following configurations of allocators:\n\n - Zero allocators, in which case plug-and-play node-ID allocation cannot be used, only nodes with statically\n configured node-ID can communicate.\n\n - One allocator, in which case the feature of plug-and-play node-ID allocation will become unavailable\n if the allocator fails. In this configuration, the role of the allocator can be performed even by a very\n resource-constrained system, e.g., a low-end microcontroller.\n\n - Three allocators, in which case the allocators will be using a replicated allocation table via a\n distributed consensus algorithm. In this configuration, the network can tolerate the loss of one\n allocator and continue to serve allocation requests. This configuration requires the allocators to\n maintain large data structures for the needs of the distributed consensus algorithm, and may therefore\n require a slightly more sophisticated computational platform, e.g., a high-end microcontroller.\n\n - Five allocators, it is the same as the three allocator configuration reviewed above except that the network\n can tolerate the loss of two allocators and still continue to serve allocation requests.\n\n In order to get a PnP node-ID, an allocatee shall have a globally unique 128-bit integer identifier, known as\n unique-ID (where \"globally unique\" means that the probability of having two nodes anywhere in the world that share\n the same unique-ID is negligibly low). This is the same value that is used in the field unique_id of the data type\n uavcan.node.GetInfo. All PnP nodes shall support the service uavcan.node.GetInfo, and they shall use the same\n unique-ID value when requesting node-ID allocation and when responding to the GetInfo requests (there may exist\n other usages of the unique-ID value, but they lie outside of the scope of the PnP protocol).\n\n During allocation, the allocatee communicates its unique-ID to the allocator (or allocators in the case of a\n redundant allocator configuration), which then use it to produce an appropriate allocation response. Unique-ID\n values are kept by allocators in the \"allocation table\" - a data structure that contains the mapping between\n unique-ID and the corresponding node-ID values. The allocation table is a write-only data structure that can\n only expand. When a new allocatee requests a PnP node-ID, its unique-ID is recorded in the allocation table,\n and all subsequent allocation requests from the same allocatee will be served with the same node-ID value.\n\n In configurations with redundant allocators, every allocator maintains a replica of the same allocation table\n (a Cyphal network cannot contain more than one allocation table, regardless of the number of allocators employed).\n While the allocation table is a write-only data structure that can only grow, it is still possible to wipe the\n table completely (as long as it is removed from all redundant allocators on the network simultaneously),\n forcing the allocators to forget known nodes and perform all future allocations anew.\n\n In the context of the following description, nodes that use a manually-configured node-ID will be referred to as\n \"static nodes\". It is assumed that allocators are always static nodes themselves since there is no other authority\n on the network that can grant a PnP node-ID, so allocators are unable to request a PnP node-ID for themselves.\n Excepting allocators, it is not recommended to mix PnP and static nodes on the same network; i.e., normally,\n a Cyphal network should contain either all static nodes, or all PnP nodes (excepting allocators). If this\n recommendation cannot be followed, the following rules of safe co-existence of PnP nodes with static nodes should\n be adopted:\n - It is safe to connect PnP nodes to the bus at any time.\n - A static node can be connected to the bus if the allocator (allocators) is (are) already aware of it.\n I.e., the static node is already listed in the allocation table.\n - A new static node (i.e., a node that does not meet the above criterion) can be connected to the bus only if\n no PnP allocation requests are happening at the moment.\n\n Due to the possibility of coexistence of static nodes with PnP nodes, allocators are tasked with monitoring\n the nodes present in the network. If the allocator detects an online node in the network the node-ID of which is\n not found in the allocation table (or the local copy thereof in the case of redundant allocators), the allocator\n shall create a new mock entry where the node-ID matches that of the newly detected node and the unique-ID is set to\n zero (i.e., a 128-bit long sequence of zero bits). This behavior ensures that PnP nodes will never be granted\n node-ID values that are already taken by static nodes. Allocators are allowed to request the true unique-ID of the\n newly detected nodes by issuing requests uavcan.node.GetInfo instead of using mock zero unique-IDs, but this is not\n required for the sake of simplicity and determinism (some nodes may fail to respond to the GetInfo request, e.g.,\n if this service is not supported). Note that in the case of redundant allocators, some of them may be relieved of\n this task due to the intrinsic properties of the distributed consensus algorithm; please refer to the documentation\n for the data type uavcan.pnp.cluster.AppendEntries for more information.\n\n The unique-ID & node-ID pair of each allocator shall be kept in the allocation table as well. It is allowed to replace\n the unique-ID values of allocators with zeros at the discretion of the implementer.\n\n As can be inferred from the above, the process of PnP node-ID allocation involves up to two types of communications:\n\n - \"Allocatee-allocator exchange\" - this communication is used when an allocatee requests a PnP node-ID from the\n allocator (or redundant allocators), and also when the allocator transmits a response back to the allocatee.\n This communication is invariant to the allocator configuration used, i.e., the allocatees are not aware of\n how many allocators are available on the network and how they are configured. In configurations with\n non-redundant (i.e., single) allocator, this is the only type of PnP allocation exchanges.\n\n - \"Allocator-allocator exchange\" - this communication is used by redundant allocators for the maintenance of\n the replicated allocation table and for other needs of the distributed consensus algorithm. Allocatees are\n completely isolated and are unaware of these exchanges. This communication is not used with the single-allocator\n configuration, since there is only one server and the allocation table is not distributed. The data types\n used for the allocator-allocator exchanges are defined in the namespace uavcan.pnp.cluster.\n\n As has been said earlier, the logic used for communication between allocators (for the needs of the maintenance of\n the distributed allocation table) is completely unrelated to the allocatees. The allocatees are unaware of these\n exchanges, and they are also unaware of the allocator configuration used on the network: single or redundant.\n As such, the documentation you're currently reading does not describe the logic and requirements of the\n allocator-allocator exchanges for redundant configurations; for that, please refer to the documentation for the\n data type uavcan.pnp.cluster.AppendEntries.\n\n Allocatee-allocator exchanges are performed using only this message type uavcan.pnp.NodeIDAllocationData. Allocators\n use it with regular message transfers; allocatees use it with anonymous message transfers. The specification and\n usage info for this data type is provided below.\n\n The general idea of the allocatee-allocator exchanges is that the allocatee communicates to the allocator its\n unique-ID and, if applicable, the preferred node-ID value that it would like to have. The allocatee uses\n anonymous message transfers of this type. The allocator performs the allocation and sends a response using\n the same message type, where the field for unique-ID is populated with the unique-ID of the requesting node\n and the field for node-ID is populated with the allocated node-ID. All exchanges from allocatee to allocator use\n single-frame transfers only (see the specification for more information on the limitations of anonymous messages).\n\n The allocatee-allocator exchange logic differs between allocators and allocatees. For allocators, the logic is\n trivial: upon reception of a request, the allocator performs an allocation and sends a response back. If the\n allocation could not be performed for any reason (e.g., the allocation table is full, or there was a failure),\n no response is sent back (i.e., the request is simply ignored); the recommended strategy for the allocatee is to\n continue sending new allocation requests until a response is granted or a higher-level system (e.g., a maintenance\n technician or some automation) intervenes to rectify the problem (e.g., by purging the allocation table).\n The allocator that could not complete an allocation for any reason is recommended to emit a diagnostic message\n with a human-readable description of the problem. For allocatees, the logic is described below.\n\n This message is used for PnP node-ID allocation on all transports where the maximum transmission unit size is\n sufficiently large. For low-MTU transports such as Classic CAN there is an older version of the definition (v1)\n that takes the low MTU into account (the unique-ID value is replaced with a short hash in order to fit the data\n into one 7-byte-long transfer).\n\n Generally, the randomly chosen values of the request period (Trequest) should be in the range from 0 to 1 seconds.\n Applications that are not concerned about the allocation time are recommended to pick higher values, as it will\n reduce interference with other nodes where faster allocations may be desirable. The random interval shall be chosen\n anew per transmission, whereas the pseudo node-ID value is allowed to stay constant per node.\n\n The source of random data for Trequest shall be likely to yield different values for participating nodes, avoiding\n common sequences. This implies that the time since boot alone is not a sufficiently robust source of randomness,\n as that would be probable to cause nodes powered up at the same time to emit colliding messages repeatedly.\n\n The response timeout is not explicitly defined for this protocol, as the allocatee will request a new allocation\n Trequest units of time later again, unless an allocation has been granted. Since the request and response messages\n are fully idempotent, accidentally repeated messages (e.g., due to benign race conditions that are inherent to this\n protocol) are harmless.\n\n On the allocatee's side the protocol is defined through the following set of rules:\n\n Rule A. On initialization:\n 1. The allocatee subscribes to this message.\n 2. The allocatee starts the Request Timer with a random interval of Trequest.\n\n Rule B. On expiration of the Request Timer:\n 1. Request Timer restarts with a random interval of Trequest (chosen anew).\n 2. The allocatee broadcasts an allocation request message, where the fields are populated as follows:\n node_id - the preferred node-ID, or the highest valid value if the allocatee doesn't have any preference.\n unique_id - the 128-bit unique-ID of the allocatee, same value that is reported via uavcan.node.GetInfo.\n\n Rule C. On an allocation message WHERE (source node-ID is non-anonymous, i.e., regular allocation response)\n AND (the field unique_id matches the allocatee's unique-ID):\n 1. Request Timer stops.\n 2. The allocatee initializes its node-ID with the received value.\n 3. The allocatee terminates its subscription to allocation messages.\n 4. Exit.\n\n As can be seen, the algorithm assumes that the allocatee will continue to emit requests at random intervals\n until an allocation is granted or the allocatee is disconnected."
10939 )]
10940 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
10941 #[repr(C, packed)]
10942 pub struct NodeIDAllocationData {
10943 #[cfg_attr(
10944 not(doctest),
10945 doc = " If the message transfer is anonymous (i.e., allocation request), this is the preferred ID.\n If the message transfer is non-anonymous (i.e., allocation response), this is the allocated ID.\n\n If the allocatee does not have any preference, it should request the highest possible node-ID. Keep in mind that\n the two highest node-ID values are reserved for network maintenance tools; requesting those is not prohibited,\n but the allocator is recommended to avoid granting these node-ID, using nearest available lower value instead.\n The allocator will traverse the allocation table starting from the preferred node-ID upward,\n until a free node-ID is found (or the first ID reserved for network maintenance tools is reached).\n If a free node-ID could not be found, the allocator will restart the search from the preferred node-ID\n downward, until a free node-ID is found."
10946 )]
10947 pub node_id: crate::uavcan::node::id_1_0::ID,
10953 #[cfg_attr(
10954 not(doctest),
10955 doc = " The unique-ID of the allocatee. This is the SAME value that is reported via uavcan.node.GetInfo.\n The value is subjected to the same set of constraints; e.g., it can't be changed while the node is running,\n and the same value should be unlikely to be used by any two different nodes anywhere in the world.\n\n If this is a non-anonymous transfer (i.e., allocation response), allocatees will match this value against their\n own unique-ID, and ignore the message if there is no match. If the IDs match, then the field node_id contains\n the allocated node-ID value for this node."
10956 )]
10957 pub unique_id: [u8; 16],
10963 }
10964 impl ::emcyphal_encoding::DataType for NodeIDAllocationData {
10965 const EXTENT_BYTES: Option<u32> = Some(48);
10967 }
10968 impl ::emcyphal_encoding::Message for NodeIDAllocationData {}
10969 impl ::emcyphal_encoding::BufferType for NodeIDAllocationData {
10970 type Buffer = ::emcyphal_encoding::StaticBuffer<18>;
10971 }
10972 impl NodeIDAllocationData {}
10973 impl ::emcyphal_encoding::Serialize for NodeIDAllocationData {
10974 fn size_bits(&self) -> usize {
10975 144
10976 }
10977 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
10978 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
10979 }
10980 }
10981 impl ::emcyphal_encoding::Deserialize for NodeIDAllocationData {
10982 fn deserialize(
10983 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
10984 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
10985 where
10986 Self: Sized,
10987 {
10988 Ok(Self::deserialize_zero_copy(cursor))
10989 }
10990 }
10991 #[test]
10992 fn test_layout() {
10993 assert_eq!(::core::mem::size_of::<NodeIDAllocationData>() * 8, 144);
10994 assert_eq!(
10995 ::core::mem::offset_of!(NodeIDAllocationData, node_id) * 8,
10996 0
10997 );
10998 assert_eq!(
10999 ::core::mem::offset_of!(NodeIDAllocationData, unique_id) * 8,
11000 16
11001 );
11002 }
11003 }
11004 }
11005 pub mod primitive {
11006 pub mod array {
11007 pub mod bit_1_0 {
11008 #[cfg_attr(
11013 not(doctest),
11014 doc = " 2048 bits + 11 bit length + 4 bit padding = 2064 bits = 258 bytes"
11015 )]
11016 pub struct Bit {
11017 pub value: ::emcyphal_encoding::bits::BitArray<256>,
11023 }
11024 impl ::emcyphal_encoding::DataType for Bit {
11025 const EXTENT_BYTES: Option<u32> = None;
11027 }
11028 impl ::emcyphal_encoding::Message for Bit {}
11029 impl ::emcyphal_encoding::BufferType for Bit {
11030 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
11031 }
11032 impl Bit {}
11033 impl ::emcyphal_encoding::Serialize for Bit {
11034 fn size_bits(&self) -> usize {
11035 16 + (self.value).len() * 1 + 0
11036 }
11037 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11038 cursor.write_aligned_u16((self.value).len() as u16);
11039 (self.value).serialize(cursor);
11040 }
11041 }
11042 impl ::emcyphal_encoding::Deserialize for Bit {
11043 fn deserialize(
11044 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11045 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11046 where
11047 Self: Sized,
11048 {
11049 Ok(Bit {
11050 value: {
11051 {
11052 let length = cursor.read_u16() as _;
11053 ::emcyphal_encoding::bits::BitArray::deserialize(length, cursor)
11054 }
11055 },
11056 })
11057 }
11058 }
11059 }
11060 pub mod integer16_1_0 {
11061 pub struct Integer16 {
11066 pub value: ::heapless::Vec<i16, 128>,
11072 }
11073 impl ::emcyphal_encoding::DataType for Integer16 {
11074 const EXTENT_BYTES: Option<u32> = None;
11076 }
11077 impl ::emcyphal_encoding::Message for Integer16 {}
11078 impl ::emcyphal_encoding::BufferType for Integer16 {
11079 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11080 }
11081 impl Integer16 {}
11082 impl ::emcyphal_encoding::Serialize for Integer16 {
11083 fn size_bits(&self) -> usize {
11084 8 + (self.value).len() * 16 + 0
11085 }
11086 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11087 cursor.write_aligned_u8((self.value).len() as u8);
11088 for value in (self.value).iter() {
11089 cursor.write_u16(*value as u16);
11090 }
11091 }
11092 }
11093 impl ::emcyphal_encoding::Deserialize for Integer16 {
11094 fn deserialize(
11095 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11096 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11097 where
11098 Self: Sized,
11099 {
11100 Ok(Integer16 {
11101 value: {
11102 let length = cursor.read_u8() as _;
11103 if length <= 128 {
11104 let mut elements = ::heapless::Vec::new();
11105 for _ in 0..length {
11106 let _ = elements.push(cursor.read_u16() as _);
11107 }
11108 elements
11109 } else {
11110 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11111 }
11112 },
11113 })
11114 }
11115 }
11116 }
11117 pub mod integer32_1_0 {
11118 pub struct Integer32 {
11123 pub value: ::heapless::Vec<i32, 64>,
11129 }
11130 impl ::emcyphal_encoding::DataType for Integer32 {
11131 const EXTENT_BYTES: Option<u32> = None;
11133 }
11134 impl ::emcyphal_encoding::Message for Integer32 {}
11135 impl ::emcyphal_encoding::BufferType for Integer32 {
11136 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11137 }
11138 impl Integer32 {}
11139 impl ::emcyphal_encoding::Serialize for Integer32 {
11140 fn size_bits(&self) -> usize {
11141 8 + (self.value).len() * 32 + 0
11142 }
11143 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11144 cursor.write_aligned_u8((self.value).len() as u8);
11145 for value in (self.value).iter() {
11146 cursor.write_u32(*value as u32);
11147 }
11148 }
11149 }
11150 impl ::emcyphal_encoding::Deserialize for Integer32 {
11151 fn deserialize(
11152 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11153 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11154 where
11155 Self: Sized,
11156 {
11157 Ok(Integer32 {
11158 value: {
11159 let length = cursor.read_u8() as _;
11160 if length <= 64 {
11161 let mut elements = ::heapless::Vec::new();
11162 for _ in 0..length {
11163 let _ = elements.push(cursor.read_u32() as _);
11164 }
11165 elements
11166 } else {
11167 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11168 }
11169 },
11170 })
11171 }
11172 }
11173 }
11174 pub mod integer64_1_0 {
11175 pub struct Integer64 {
11180 pub value: ::heapless::Vec<i64, 32>,
11186 }
11187 impl ::emcyphal_encoding::DataType for Integer64 {
11188 const EXTENT_BYTES: Option<u32> = None;
11190 }
11191 impl ::emcyphal_encoding::Message for Integer64 {}
11192 impl ::emcyphal_encoding::BufferType for Integer64 {
11193 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11194 }
11195 impl Integer64 {}
11196 impl ::emcyphal_encoding::Serialize for Integer64 {
11197 fn size_bits(&self) -> usize {
11198 8 + (self.value).len() * 64 + 0
11199 }
11200 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11201 cursor.write_aligned_u8((self.value).len() as u8);
11202 for value in (self.value).iter() {
11203 cursor.write_u64(*value as u64);
11204 }
11205 }
11206 }
11207 impl ::emcyphal_encoding::Deserialize for Integer64 {
11208 fn deserialize(
11209 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11210 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11211 where
11212 Self: Sized,
11213 {
11214 Ok(Integer64 {
11215 value: {
11216 let length = cursor.read_u8() as _;
11217 if length <= 32 {
11218 let mut elements = ::heapless::Vec::new();
11219 for _ in 0..length {
11220 let _ = elements.push(cursor.read_u64() as _);
11221 }
11222 elements
11223 } else {
11224 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11225 }
11226 },
11227 })
11228 }
11229 }
11230 }
11231 pub mod integer8_1_0 {
11232 pub struct Integer8 {
11237 pub value: ::heapless::Vec<i8, 256>,
11243 }
11244 impl ::emcyphal_encoding::DataType for Integer8 {
11245 const EXTENT_BYTES: Option<u32> = None;
11247 }
11248 impl ::emcyphal_encoding::Message for Integer8 {}
11249 impl ::emcyphal_encoding::BufferType for Integer8 {
11250 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
11251 }
11252 impl Integer8 {}
11253 impl ::emcyphal_encoding::Serialize for Integer8 {
11254 fn size_bits(&self) -> usize {
11255 16 + (self.value).len() * 8 + 0
11256 }
11257 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11258 cursor.write_aligned_u16((self.value).len() as u16);
11259 for value in (self.value).iter() {
11260 cursor.write_u8(*value as u8);
11261 }
11262 }
11263 }
11264 impl ::emcyphal_encoding::Deserialize for Integer8 {
11265 fn deserialize(
11266 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11267 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11268 where
11269 Self: Sized,
11270 {
11271 Ok(Integer8 {
11272 value: {
11273 let length = cursor.read_u16() as _;
11274 if length <= 256 {
11275 let mut elements = ::heapless::Vec::new();
11276 for _ in 0..length {
11277 let _ = elements.push(cursor.read_u8() as _);
11278 }
11279 elements
11280 } else {
11281 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11282 }
11283 },
11284 })
11285 }
11286 }
11287 }
11288 pub mod natural16_1_0 {
11289 pub struct Natural16 {
11294 pub value: ::heapless::Vec<u16, 128>,
11300 }
11301 impl ::emcyphal_encoding::DataType for Natural16 {
11302 const EXTENT_BYTES: Option<u32> = None;
11304 }
11305 impl ::emcyphal_encoding::Message for Natural16 {}
11306 impl ::emcyphal_encoding::BufferType for Natural16 {
11307 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11308 }
11309 impl Natural16 {}
11310 impl ::emcyphal_encoding::Serialize for Natural16 {
11311 fn size_bits(&self) -> usize {
11312 8 + (self.value).len() * 16 + 0
11313 }
11314 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11315 cursor.write_aligned_u8((self.value).len() as u8);
11316 for value in (self.value).iter() {
11317 cursor.write_u16(*value);
11318 }
11319 }
11320 }
11321 impl ::emcyphal_encoding::Deserialize for Natural16 {
11322 fn deserialize(
11323 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11324 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11325 where
11326 Self: Sized,
11327 {
11328 Ok(Natural16 {
11329 value: {
11330 let length = cursor.read_u8() as _;
11331 if length <= 128 {
11332 let mut elements = ::heapless::Vec::new();
11333 for _ in 0..length {
11334 let _ = elements.push(cursor.read_u16() as _);
11335 }
11336 elements
11337 } else {
11338 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11339 }
11340 },
11341 })
11342 }
11343 }
11344 }
11345 pub mod natural32_1_0 {
11346 pub struct Natural32 {
11351 pub value: ::heapless::Vec<u32, 64>,
11357 }
11358 impl ::emcyphal_encoding::DataType for Natural32 {
11359 const EXTENT_BYTES: Option<u32> = None;
11361 }
11362 impl ::emcyphal_encoding::Message for Natural32 {}
11363 impl ::emcyphal_encoding::BufferType for Natural32 {
11364 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11365 }
11366 impl Natural32 {}
11367 impl ::emcyphal_encoding::Serialize for Natural32 {
11368 fn size_bits(&self) -> usize {
11369 8 + (self.value).len() * 32 + 0
11370 }
11371 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11372 cursor.write_aligned_u8((self.value).len() as u8);
11373 for value in (self.value).iter() {
11374 cursor.write_u32(*value);
11375 }
11376 }
11377 }
11378 impl ::emcyphal_encoding::Deserialize for Natural32 {
11379 fn deserialize(
11380 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11381 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11382 where
11383 Self: Sized,
11384 {
11385 Ok(Natural32 {
11386 value: {
11387 let length = cursor.read_u8() as _;
11388 if length <= 64 {
11389 let mut elements = ::heapless::Vec::new();
11390 for _ in 0..length {
11391 let _ = elements.push(cursor.read_u32() as _);
11392 }
11393 elements
11394 } else {
11395 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11396 }
11397 },
11398 })
11399 }
11400 }
11401 }
11402 pub mod natural64_1_0 {
11403 pub struct Natural64 {
11408 pub value: ::heapless::Vec<u64, 32>,
11414 }
11415 impl ::emcyphal_encoding::DataType for Natural64 {
11416 const EXTENT_BYTES: Option<u32> = None;
11418 }
11419 impl ::emcyphal_encoding::Message for Natural64 {}
11420 impl ::emcyphal_encoding::BufferType for Natural64 {
11421 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11422 }
11423 impl Natural64 {}
11424 impl ::emcyphal_encoding::Serialize for Natural64 {
11425 fn size_bits(&self) -> usize {
11426 8 + (self.value).len() * 64 + 0
11427 }
11428 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11429 cursor.write_aligned_u8((self.value).len() as u8);
11430 for value in (self.value).iter() {
11431 cursor.write_u64(*value);
11432 }
11433 }
11434 }
11435 impl ::emcyphal_encoding::Deserialize for Natural64 {
11436 fn deserialize(
11437 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11438 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11439 where
11440 Self: Sized,
11441 {
11442 Ok(Natural64 {
11443 value: {
11444 let length = cursor.read_u8() as _;
11445 if length <= 32 {
11446 let mut elements = ::heapless::Vec::new();
11447 for _ in 0..length {
11448 let _ = elements.push(cursor.read_u64() as _);
11449 }
11450 elements
11451 } else {
11452 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11453 }
11454 },
11455 })
11456 }
11457 }
11458 }
11459 pub mod natural8_1_0 {
11460 pub struct Natural8 {
11465 pub value: ::heapless::Vec<u8, 256>,
11471 }
11472 impl ::emcyphal_encoding::DataType for Natural8 {
11473 const EXTENT_BYTES: Option<u32> = None;
11475 }
11476 impl ::emcyphal_encoding::Message for Natural8 {}
11477 impl ::emcyphal_encoding::BufferType for Natural8 {
11478 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
11479 }
11480 impl Natural8 {}
11481 impl ::emcyphal_encoding::Serialize for Natural8 {
11482 fn size_bits(&self) -> usize {
11483 16 + (self.value).len() * 8 + 0
11484 }
11485 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11486 cursor.write_aligned_u16((self.value).len() as u16);
11487 cursor.write_bytes(&(self.value)[..]);
11488 }
11489 }
11490 impl ::emcyphal_encoding::Deserialize for Natural8 {
11491 fn deserialize(
11492 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11493 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11494 where
11495 Self: Sized,
11496 {
11497 Ok(Natural8 {
11498 value: {
11499 let length = cursor.read_u16() as _;
11500 if length <= 256 {
11501 let mut elements = ::heapless::Vec::new();
11502 for _ in 0..length {
11503 let _ = elements.push(cursor.read_u8() as _);
11504 }
11505 elements
11506 } else {
11507 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11508 }
11509 },
11510 })
11511 }
11512 }
11513 }
11514 pub mod real16_1_0 {
11515 #[cfg_attr(not(doctest), doc = " Exactly representable integers: [-2048, +2048]")]
11520 pub struct Real16 {
11521 pub value: ::heapless::Vec<::half::f16, 128>,
11527 }
11528 impl ::emcyphal_encoding::DataType for Real16 {
11529 const EXTENT_BYTES: Option<u32> = None;
11531 }
11532 impl ::emcyphal_encoding::Message for Real16 {}
11533 impl ::emcyphal_encoding::BufferType for Real16 {
11534 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11535 }
11536 impl Real16 {}
11537 impl ::emcyphal_encoding::Serialize for Real16 {
11538 fn size_bits(&self) -> usize {
11539 8 + (self.value).len() * 16 + 0
11540 }
11541 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11542 cursor.write_aligned_u8((self.value).len() as u8);
11543 for value in (self.value).iter() {
11544 cursor.write_f16(*value);
11545 }
11546 }
11547 }
11548 impl ::emcyphal_encoding::Deserialize for Real16 {
11549 fn deserialize(
11550 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11551 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11552 where
11553 Self: Sized,
11554 {
11555 Ok(Real16 {
11556 value: {
11557 let length = cursor.read_u8() as _;
11558 if length <= 128 {
11559 let mut elements = ::heapless::Vec::new();
11560 for _ in 0..length {
11561 let _ = elements.push(cursor.read_f16());
11562 }
11563 elements
11564 } else {
11565 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11566 }
11567 },
11568 })
11569 }
11570 }
11571 }
11572 pub mod real32_1_0 {
11573 #[cfg_attr(
11578 not(doctest),
11579 doc = " Exactly representable integers: [-16777216, +16777216]"
11580 )]
11581 pub struct Real32 {
11582 pub value: ::heapless::Vec<f32, 64>,
11588 }
11589 impl ::emcyphal_encoding::DataType for Real32 {
11590 const EXTENT_BYTES: Option<u32> = None;
11592 }
11593 impl ::emcyphal_encoding::Message for Real32 {}
11594 impl ::emcyphal_encoding::BufferType for Real32 {
11595 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11596 }
11597 impl Real32 {}
11598 impl ::emcyphal_encoding::Serialize for Real32 {
11599 fn size_bits(&self) -> usize {
11600 8 + (self.value).len() * 32 + 0
11601 }
11602 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11603 cursor.write_aligned_u8((self.value).len() as u8);
11604 for value in (self.value).iter() {
11605 cursor.write_f32(*value);
11606 }
11607 }
11608 }
11609 impl ::emcyphal_encoding::Deserialize for Real32 {
11610 fn deserialize(
11611 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11612 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11613 where
11614 Self: Sized,
11615 {
11616 Ok(Real32 {
11617 value: {
11618 let length = cursor.read_u8() as _;
11619 if length <= 64 {
11620 let mut elements = ::heapless::Vec::new();
11621 for _ in 0..length {
11622 let _ = elements.push(cursor.read_f32());
11623 }
11624 elements
11625 } else {
11626 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11627 }
11628 },
11629 })
11630 }
11631 }
11632 }
11633 pub mod real64_1_0 {
11634 #[cfg_attr(
11639 not(doctest),
11640 doc = " Exactly representable integers: [-2**53, +2**53]"
11641 )]
11642 pub struct Real64 {
11643 pub value: ::heapless::Vec<f64, 32>,
11649 }
11650 impl ::emcyphal_encoding::DataType for Real64 {
11651 const EXTENT_BYTES: Option<u32> = None;
11653 }
11654 impl ::emcyphal_encoding::Message for Real64 {}
11655 impl ::emcyphal_encoding::BufferType for Real64 {
11656 type Buffer = ::emcyphal_encoding::StaticBuffer<257>;
11657 }
11658 impl Real64 {}
11659 impl ::emcyphal_encoding::Serialize for Real64 {
11660 fn size_bits(&self) -> usize {
11661 8 + (self.value).len() * 64 + 0
11662 }
11663 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11664 cursor.write_aligned_u8((self.value).len() as u8);
11665 for value in (self.value).iter() {
11666 cursor.write_f64(*value);
11667 }
11668 }
11669 }
11670 impl ::emcyphal_encoding::Deserialize for Real64 {
11671 fn deserialize(
11672 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11673 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11674 where
11675 Self: Sized,
11676 {
11677 Ok(Real64 {
11678 value: {
11679 let length = cursor.read_u8() as _;
11680 if length <= 32 {
11681 let mut elements = ::heapless::Vec::new();
11682 for _ in 0..length {
11683 let _ = elements.push(cursor.read_f64());
11684 }
11685 elements
11686 } else {
11687 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
11688 }
11689 },
11690 })
11691 }
11692 }
11693 }
11694 }
11695 pub mod empty_1_0 {
11696 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11701 #[repr(C, packed)]
11702 pub struct Empty {}
11703 impl ::emcyphal_encoding::DataType for Empty {
11704 const EXTENT_BYTES: Option<u32> = None;
11706 }
11707 impl ::emcyphal_encoding::Message for Empty {}
11708 impl ::emcyphal_encoding::BufferType for Empty {
11709 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
11710 }
11711 impl Empty {}
11712 impl ::emcyphal_encoding::Serialize for Empty {
11713 fn size_bits(&self) -> usize {
11714 0
11715 }
11716 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11717 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
11718 }
11719 }
11720 impl ::emcyphal_encoding::Deserialize for Empty {
11721 fn deserialize(
11722 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11723 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11724 where
11725 Self: Sized,
11726 {
11727 Ok(Self::deserialize_zero_copy(cursor))
11728 }
11729 }
11730 #[test]
11731 fn test_layout() {
11732 assert_eq!(::core::mem::size_of::<Empty>() * 8, 0);
11733 }
11734 }
11735 pub mod scalar {
11736 pub mod bit_1_0 {
11737 pub struct Bit {
11742 pub value: bool,
11748 }
11749 impl ::emcyphal_encoding::DataType for Bit {
11750 const EXTENT_BYTES: Option<u32> = None;
11752 }
11753 impl ::emcyphal_encoding::Message for Bit {}
11754 impl ::emcyphal_encoding::BufferType for Bit {
11755 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
11756 }
11757 impl Bit {}
11758 impl ::emcyphal_encoding::Serialize for Bit {
11759 fn size_bits(&self) -> usize {
11760 8
11761 }
11762 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11763 cursor.write_bool(self.value);
11764 }
11765 }
11766 impl ::emcyphal_encoding::Deserialize for Bit {
11767 fn deserialize(
11768 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11769 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11770 where
11771 Self: Sized,
11772 {
11773 Ok(Bit {
11774 value: { cursor.read_bool() },
11775 })
11776 }
11777 }
11778 }
11779 pub mod integer16_1_0 {
11780 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11785 #[repr(C, packed)]
11786 pub struct Integer16 {
11787 pub value: i16,
11793 }
11794 impl ::emcyphal_encoding::DataType for Integer16 {
11795 const EXTENT_BYTES: Option<u32> = None;
11797 }
11798 impl ::emcyphal_encoding::Message for Integer16 {}
11799 impl ::emcyphal_encoding::BufferType for Integer16 {
11800 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
11801 }
11802 impl Integer16 {}
11803 impl ::emcyphal_encoding::Serialize for Integer16 {
11804 fn size_bits(&self) -> usize {
11805 16
11806 }
11807 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11808 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
11809 }
11810 }
11811 impl ::emcyphal_encoding::Deserialize for Integer16 {
11812 fn deserialize(
11813 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11814 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11815 where
11816 Self: Sized,
11817 {
11818 Ok(Self::deserialize_zero_copy(cursor))
11819 }
11820 }
11821 #[test]
11822 fn test_layout() {
11823 assert_eq!(::core::mem::size_of::<Integer16>() * 8, 16);
11824 assert_eq!(::core::mem::offset_of!(Integer16, value) * 8, 0);
11825 }
11826 }
11827 pub mod integer32_1_0 {
11828 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11833 #[repr(C, packed)]
11834 pub struct Integer32 {
11835 pub value: i32,
11841 }
11842 impl ::emcyphal_encoding::DataType for Integer32 {
11843 const EXTENT_BYTES: Option<u32> = None;
11845 }
11846 impl ::emcyphal_encoding::Message for Integer32 {}
11847 impl ::emcyphal_encoding::BufferType for Integer32 {
11848 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
11849 }
11850 impl Integer32 {}
11851 impl ::emcyphal_encoding::Serialize for Integer32 {
11852 fn size_bits(&self) -> usize {
11853 32
11854 }
11855 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11856 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
11857 }
11858 }
11859 impl ::emcyphal_encoding::Deserialize for Integer32 {
11860 fn deserialize(
11861 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11862 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11863 where
11864 Self: Sized,
11865 {
11866 Ok(Self::deserialize_zero_copy(cursor))
11867 }
11868 }
11869 #[test]
11870 fn test_layout() {
11871 assert_eq!(::core::mem::size_of::<Integer32>() * 8, 32);
11872 assert_eq!(::core::mem::offset_of!(Integer32, value) * 8, 0);
11873 }
11874 }
11875 pub mod integer64_1_0 {
11876 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11881 #[repr(C, packed)]
11882 pub struct Integer64 {
11883 pub value: i64,
11889 }
11890 impl ::emcyphal_encoding::DataType for Integer64 {
11891 const EXTENT_BYTES: Option<u32> = None;
11893 }
11894 impl ::emcyphal_encoding::Message for Integer64 {}
11895 impl ::emcyphal_encoding::BufferType for Integer64 {
11896 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
11897 }
11898 impl Integer64 {}
11899 impl ::emcyphal_encoding::Serialize for Integer64 {
11900 fn size_bits(&self) -> usize {
11901 64
11902 }
11903 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11904 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
11905 }
11906 }
11907 impl ::emcyphal_encoding::Deserialize for Integer64 {
11908 fn deserialize(
11909 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11910 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11911 where
11912 Self: Sized,
11913 {
11914 Ok(Self::deserialize_zero_copy(cursor))
11915 }
11916 }
11917 #[test]
11918 fn test_layout() {
11919 assert_eq!(::core::mem::size_of::<Integer64>() * 8, 64);
11920 assert_eq!(::core::mem::offset_of!(Integer64, value) * 8, 0);
11921 }
11922 }
11923 pub mod integer8_1_0 {
11924 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11929 #[repr(C, packed)]
11930 pub struct Integer8 {
11931 pub value: i8,
11937 }
11938 impl ::emcyphal_encoding::DataType for Integer8 {
11939 const EXTENT_BYTES: Option<u32> = None;
11941 }
11942 impl ::emcyphal_encoding::Message for Integer8 {}
11943 impl ::emcyphal_encoding::BufferType for Integer8 {
11944 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
11945 }
11946 impl Integer8 {}
11947 impl ::emcyphal_encoding::Serialize for Integer8 {
11948 fn size_bits(&self) -> usize {
11949 8
11950 }
11951 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
11952 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
11953 }
11954 }
11955 impl ::emcyphal_encoding::Deserialize for Integer8 {
11956 fn deserialize(
11957 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
11958 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
11959 where
11960 Self: Sized,
11961 {
11962 Ok(Self::deserialize_zero_copy(cursor))
11963 }
11964 }
11965 #[test]
11966 fn test_layout() {
11967 assert_eq!(::core::mem::size_of::<Integer8>() * 8, 8);
11968 assert_eq!(::core::mem::offset_of!(Integer8, value) * 8, 0);
11969 }
11970 }
11971 pub mod natural16_1_0 {
11972 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
11977 #[repr(C, packed)]
11978 pub struct Natural16 {
11979 pub value: u16,
11985 }
11986 impl ::emcyphal_encoding::DataType for Natural16 {
11987 const EXTENT_BYTES: Option<u32> = None;
11989 }
11990 impl ::emcyphal_encoding::Message for Natural16 {}
11991 impl ::emcyphal_encoding::BufferType for Natural16 {
11992 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
11993 }
11994 impl Natural16 {}
11995 impl ::emcyphal_encoding::Serialize for Natural16 {
11996 fn size_bits(&self) -> usize {
11997 16
11998 }
11999 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12000 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12001 }
12002 }
12003 impl ::emcyphal_encoding::Deserialize for Natural16 {
12004 fn deserialize(
12005 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12006 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12007 where
12008 Self: Sized,
12009 {
12010 Ok(Self::deserialize_zero_copy(cursor))
12011 }
12012 }
12013 #[test]
12014 fn test_layout() {
12015 assert_eq!(::core::mem::size_of::<Natural16>() * 8, 16);
12016 assert_eq!(::core::mem::offset_of!(Natural16, value) * 8, 0);
12017 }
12018 }
12019 pub mod natural32_1_0 {
12020 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12025 #[repr(C, packed)]
12026 pub struct Natural32 {
12027 pub value: u32,
12033 }
12034 impl ::emcyphal_encoding::DataType for Natural32 {
12035 const EXTENT_BYTES: Option<u32> = None;
12037 }
12038 impl ::emcyphal_encoding::Message for Natural32 {}
12039 impl ::emcyphal_encoding::BufferType for Natural32 {
12040 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
12041 }
12042 impl Natural32 {}
12043 impl ::emcyphal_encoding::Serialize for Natural32 {
12044 fn size_bits(&self) -> usize {
12045 32
12046 }
12047 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12048 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12049 }
12050 }
12051 impl ::emcyphal_encoding::Deserialize for Natural32 {
12052 fn deserialize(
12053 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12054 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12055 where
12056 Self: Sized,
12057 {
12058 Ok(Self::deserialize_zero_copy(cursor))
12059 }
12060 }
12061 #[test]
12062 fn test_layout() {
12063 assert_eq!(::core::mem::size_of::<Natural32>() * 8, 32);
12064 assert_eq!(::core::mem::offset_of!(Natural32, value) * 8, 0);
12065 }
12066 }
12067 pub mod natural64_1_0 {
12068 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12073 #[repr(C, packed)]
12074 pub struct Natural64 {
12075 pub value: u64,
12081 }
12082 impl ::emcyphal_encoding::DataType for Natural64 {
12083 const EXTENT_BYTES: Option<u32> = None;
12085 }
12086 impl ::emcyphal_encoding::Message for Natural64 {}
12087 impl ::emcyphal_encoding::BufferType for Natural64 {
12088 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
12089 }
12090 impl Natural64 {}
12091 impl ::emcyphal_encoding::Serialize for Natural64 {
12092 fn size_bits(&self) -> usize {
12093 64
12094 }
12095 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12096 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12097 }
12098 }
12099 impl ::emcyphal_encoding::Deserialize for Natural64 {
12100 fn deserialize(
12101 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12102 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12103 where
12104 Self: Sized,
12105 {
12106 Ok(Self::deserialize_zero_copy(cursor))
12107 }
12108 }
12109 #[test]
12110 fn test_layout() {
12111 assert_eq!(::core::mem::size_of::<Natural64>() * 8, 64);
12112 assert_eq!(::core::mem::offset_of!(Natural64, value) * 8, 0);
12113 }
12114 }
12115 pub mod natural8_1_0 {
12116 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12121 #[repr(C, packed)]
12122 pub struct Natural8 {
12123 pub value: u8,
12129 }
12130 impl ::emcyphal_encoding::DataType for Natural8 {
12131 const EXTENT_BYTES: Option<u32> = None;
12133 }
12134 impl ::emcyphal_encoding::Message for Natural8 {}
12135 impl ::emcyphal_encoding::BufferType for Natural8 {
12136 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
12137 }
12138 impl Natural8 {}
12139 impl ::emcyphal_encoding::Serialize for Natural8 {
12140 fn size_bits(&self) -> usize {
12141 8
12142 }
12143 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12144 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12145 }
12146 }
12147 impl ::emcyphal_encoding::Deserialize for Natural8 {
12148 fn deserialize(
12149 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12150 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12151 where
12152 Self: Sized,
12153 {
12154 Ok(Self::deserialize_zero_copy(cursor))
12155 }
12156 }
12157 #[test]
12158 fn test_layout() {
12159 assert_eq!(::core::mem::size_of::<Natural8>() * 8, 8);
12160 assert_eq!(::core::mem::offset_of!(Natural8, value) * 8, 0);
12161 }
12162 }
12163 pub mod real16_1_0 {
12164 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12169 #[repr(C, packed)]
12170 pub struct Real16 {
12171 #[cfg_attr(
12172 not(doctest),
12173 doc = " Exactly representable integers: [-2048, +2048]"
12174 )]
12175 pub value: ::half::f16,
12181 }
12182 impl ::emcyphal_encoding::DataType for Real16 {
12183 const EXTENT_BYTES: Option<u32> = None;
12185 }
12186 impl ::emcyphal_encoding::Message for Real16 {}
12187 impl ::emcyphal_encoding::BufferType for Real16 {
12188 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
12189 }
12190 impl Real16 {}
12191 impl ::emcyphal_encoding::Serialize for Real16 {
12192 fn size_bits(&self) -> usize {
12193 16
12194 }
12195 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12196 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12197 }
12198 }
12199 impl ::emcyphal_encoding::Deserialize for Real16 {
12200 fn deserialize(
12201 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12202 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12203 where
12204 Self: Sized,
12205 {
12206 Ok(Self::deserialize_zero_copy(cursor))
12207 }
12208 }
12209 #[test]
12210 fn test_layout() {
12211 assert_eq!(::core::mem::size_of::<Real16>() * 8, 16);
12212 assert_eq!(::core::mem::offset_of!(Real16, value) * 8, 0);
12213 }
12214 }
12215 pub mod real32_1_0 {
12216 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12221 #[repr(C, packed)]
12222 pub struct Real32 {
12223 #[cfg_attr(
12224 not(doctest),
12225 doc = " Exactly representable integers: [-16777216, +16777216]"
12226 )]
12227 pub value: f32,
12233 }
12234 impl ::emcyphal_encoding::DataType for Real32 {
12235 const EXTENT_BYTES: Option<u32> = None;
12237 }
12238 impl ::emcyphal_encoding::Message for Real32 {}
12239 impl ::emcyphal_encoding::BufferType for Real32 {
12240 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
12241 }
12242 impl Real32 {}
12243 impl ::emcyphal_encoding::Serialize for Real32 {
12244 fn size_bits(&self) -> usize {
12245 32
12246 }
12247 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12248 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12249 }
12250 }
12251 impl ::emcyphal_encoding::Deserialize for Real32 {
12252 fn deserialize(
12253 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12254 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12255 where
12256 Self: Sized,
12257 {
12258 Ok(Self::deserialize_zero_copy(cursor))
12259 }
12260 }
12261 #[test]
12262 fn test_layout() {
12263 assert_eq!(::core::mem::size_of::<Real32>() * 8, 32);
12264 assert_eq!(::core::mem::offset_of!(Real32, value) * 8, 0);
12265 }
12266 }
12267 pub mod real64_1_0 {
12268 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12273 #[repr(C, packed)]
12274 pub struct Real64 {
12275 #[cfg_attr(
12276 not(doctest),
12277 doc = " Exactly representable integers: [-2**53, +2**53]"
12278 )]
12279 pub value: f64,
12285 }
12286 impl ::emcyphal_encoding::DataType for Real64 {
12287 const EXTENT_BYTES: Option<u32> = None;
12289 }
12290 impl ::emcyphal_encoding::Message for Real64 {}
12291 impl ::emcyphal_encoding::BufferType for Real64 {
12292 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
12293 }
12294 impl Real64 {}
12295 impl ::emcyphal_encoding::Serialize for Real64 {
12296 fn size_bits(&self) -> usize {
12297 64
12298 }
12299 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12300 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12301 }
12302 }
12303 impl ::emcyphal_encoding::Deserialize for Real64 {
12304 fn deserialize(
12305 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12306 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12307 where
12308 Self: Sized,
12309 {
12310 Ok(Self::deserialize_zero_copy(cursor))
12311 }
12312 }
12313 #[test]
12314 fn test_layout() {
12315 assert_eq!(::core::mem::size_of::<Real64>() * 8, 64);
12316 assert_eq!(::core::mem::offset_of!(Real64, value) * 8, 0);
12317 }
12318 }
12319 }
12320 pub mod string_1_0 {
12321 #[cfg_attr(
12326 not(doctest),
12327 doc = " A UTF8-encoded string of text.\n Since the string is represented as a dynamic array of bytes, it is not null-terminated. Like Pascal string."
12328 )]
12329 pub struct String {
12330 pub value: ::heapless::Vec<u8, 256>,
12336 }
12337 impl ::emcyphal_encoding::DataType for String {
12338 const EXTENT_BYTES: Option<u32> = None;
12340 }
12341 impl ::emcyphal_encoding::Message for String {}
12342 impl ::emcyphal_encoding::BufferType for String {
12343 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
12344 }
12345 impl String {}
12346 impl ::emcyphal_encoding::Serialize for String {
12347 fn size_bits(&self) -> usize {
12348 16 + (self.value).len() * 8 + 0
12349 }
12350 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12351 cursor.write_aligned_u16((self.value).len() as u16);
12352 cursor.write_bytes(&(self.value)[..]);
12353 }
12354 }
12355 impl ::emcyphal_encoding::Deserialize for String {
12356 fn deserialize(
12357 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12358 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12359 where
12360 Self: Sized,
12361 {
12362 Ok(String {
12363 value: {
12364 let length = cursor.read_u16() as _;
12365 if length <= 256 {
12366 let mut elements = ::heapless::Vec::new();
12367 for _ in 0..length {
12368 let _ = elements.push(cursor.read_u8() as _);
12369 }
12370 elements
12371 } else {
12372 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
12373 }
12374 },
12375 })
12376 }
12377 }
12378 }
12379 pub mod unstructured_1_0 {
12380 #[cfg_attr(
12385 not(doctest),
12386 doc = " An unstructured collection of bytes, e.g., raw binary image."
12387 )]
12388 pub struct Unstructured {
12389 pub value: ::heapless::Vec<u8, 256>,
12395 }
12396 impl ::emcyphal_encoding::DataType for Unstructured {
12397 const EXTENT_BYTES: Option<u32> = None;
12399 }
12400 impl ::emcyphal_encoding::Message for Unstructured {}
12401 impl ::emcyphal_encoding::BufferType for Unstructured {
12402 type Buffer = ::emcyphal_encoding::StaticBuffer<258>;
12403 }
12404 impl Unstructured {}
12405 impl ::emcyphal_encoding::Serialize for Unstructured {
12406 fn size_bits(&self) -> usize {
12407 16 + (self.value).len() * 8 + 0
12408 }
12409 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12410 cursor.write_aligned_u16((self.value).len() as u16);
12411 cursor.write_bytes(&(self.value)[..]);
12412 }
12413 }
12414 impl ::emcyphal_encoding::Deserialize for Unstructured {
12415 fn deserialize(
12416 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12417 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12418 where
12419 Self: Sized,
12420 {
12421 Ok(Unstructured {
12422 value: {
12423 let length = cursor.read_u16() as _;
12424 if length <= 256 {
12425 let mut elements = ::heapless::Vec::new();
12426 for _ in 0..length {
12427 let _ = elements.push(cursor.read_u8() as _);
12428 }
12429 elements
12430 } else {
12431 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
12432 }
12433 },
12434 })
12435 }
12436 }
12437 }
12438 }
12439 pub mod register {
12440 pub mod access_1_0 {
12441 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
12442 pub const SERVICE: ::emcyphal_core::ServiceId =
12443 ::emcyphal_core::ServiceId::from_u16_truncating(384);
12444
12445 #[cfg_attr(
12450 not(doctest),
12451 doc = " Registers are strongly-typed named values used to store the configuration parameters of a node.\n This service is used to write and read a register.\n\n\n READ/WRITE BEHAVIORS\n\n The write operation is performed first, unless skipped by sending an empty value in the request.\n The server may attempt to convert the type of the supplied value to the correct type if there is a type mismatch\n (e.g. uint8 may be converted to uint16); however, servers are not required to perform implicit type conversion,\n and the rules of such conversion are not explicitly specified, so this behavior should not be relied upon.\n\n On the next step the register will be read regardless of the outcome of the write operation. As such, if the write\n operation could not be performed (e.g. due to a type mismatch or any other issue), the register will retain its old\n value. By evaluating the response the caller can determine whether the register was written successfully.\n\n The write-read sequence is not guaranteed to be atomic, meaning that external influences may cause the register to\n change its value between the write and the subsequent read operation. The caller is responsible for handling that\n case properly.\n\n The timestamp provided in the response corresponds to the time when the register was read. The timestamp may\n be empty if the server does not support timestamping or its clock is not (yet) synchronized with the network.\n\n If only read is desired, but not write, the caller shall provide a value of type 'empty'. That will signal the server\n that the write operation shall be skipped, and it will proceed to read the register immediately.\n\n If the requested register does not exist, the write operation will have no effect and the returned value will be\n empty. Existing registers should not return 'empty' when read since that would make them indistinguishable from\n nonexistent registers.\n\n\n REGISTER DEFINITION REQUIREMENTS\n\n Registers shall never change their type or flags as long as the server is running. Meaning that:\n - Mutability and persistence flags cannot change their states.\n - Read operations shall always return values of the same type and same dimensionality.\n The dimensionality requirement does not apply to inherently variable-length values such as strings and\n unstructured chunks.\n\n Register name should contain only:\n - Lowercase ASCII alphanumeric characters (a-z, 0-9)\n - Full stop (.)\n - Low line (underscore) (_)\n With the following limitations/recommendations:\n - The name shall not begin with a decimal digit (0-9).\n - The name shall neither begin nor end with a full stop.\n - A low line shall not be followed by a non-alphanumeric character.\n - The name should contain at least one full stop character.\n Other patterns and ASCII characters are reserved for special function registers (introduced below).\n\n\n ENVIRONMENT VARIABLES\n\n This section applies only to software nodes executed in a high-level operating system that supports environment\n variables or an equivalent mechanism.\n\n When a software node is launched, it is usually necessary to provide some of its configuration information early,\n particularly that which is related to Cyphal networking, before the node is started. Environment variables offer\n a convenient way of addressing this. Software nodes that support the register interface should evaluate the\n available environment variables during initialization and update their registers (whether they are stored in\n a persistent storage or in memory) accoringly. This should be completed before the first register read access.\n\n A register name is mapped to an environment variable name as follows:\n - the name is upper-cased;\n - full stop characters are replaced with double low line characters.\n For example: 'motor.inductance_dq' is mapped to 'MOTOR__INDUCTANCE_DQ'.\n\n Register values are represented in environment variables as follows:\n - string: utf-8 or platform-specific\n - unstructured: as-is\n - bit, integer*, natural*, real*: space-separated decimals\n\n If an environment variable matches the name of an existing register but its value cannot be converted to the\n register's type, an error should be raised.\n\n If an environment variable does not match the name of any register, it may be ignored. However, if the implementation\n can reliably deduce the type and purpose of the register, it may create one automatically. This provision is to\n support applications where the register schema may be altered by configuration.\n\n\n SPECIAL FUNCTION REGISTERS\n\n The following optional special function register names are defined:\n - suffix '<' is used to define an immutable persistent value that contains the maximum value\n of the respective register.\n - suffix '>' is like above, used to define the minimum value of the respective register.\n - suffix '=' is like above, used to define the default value of the respective register.\n - prefix '*' is reserved for raw memory access (to be defined later).\n Examples:\n - register name \"system.parameter\"\n - maximum value is contained in the register named \"system.parameter<\" (optional)\n - minimum value is contained in the register named \"system.parameter>\" (optional)\n - default value is contained in the register named \"system.parameter=\" (optional)\n\n The type and dimensionality of the special function registers containing the minimum, maximum, and the default\n value of a register shall be the same as those of the register they relate to.\n\n If a written value exceeds the minimum/maximum specified by the respective special function registers,\n the server may either adjust the value automatically, or to retain the old value, depending on which behavior\n suits the objectives of the application better.\n The values of registers containing non-scalar numerical entities should be compared elementwise.\n\n\n STANDARD REGISTERS\n\n The following table specifies the register name patterns that are reserved by the specification for\n common functions. These conventions are not mandatory to follow, but implementers are recommended to adhere because\n they enable enhanced introspection capabilities and simplify device configuration and diagnostics.\n\n REGISTER NAME PATTERN TYPE FLAGS RECOMMENDED DEFAULT\n =====================================================================================================================\n\n uavcan.node.id natural16[1] mutable, persistent 65535 (unset/PnP)\n\n Contains the node-ID of the local node. Values above the maximum valid node-ID for the current transport\n indicate that the node-ID is not set; if plug-and-play is supported, it will be used by the node to obtain an\n automatic node-ID. Invalid values other than 65535 should be avoided for consistency.\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.node.description string mutable, persistent (empty)\n\n User/integrator-defined, human-readable description of this specific node.\n This is intended for use by a system integrator and should not be set by the manufacturer of a component.\n For example: on a quad-rotor drone this might read \"motor 2\" for one of the ESC nodes.\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.pub.PORT_NAME.id natural16[1] mutable, persistent 65535 (unset, invalid)\n uavcan.sub.PORT_NAME.id ditto ditto ditto\n uavcan.cln.PORT_NAME.id ditto ditto ditto\n uavcan.srv.PORT_NAME.id ditto ditto ditto\n\n Publication/subscription/client/server port-ID, respectively. These registers are configured by the system integrator\n or an autoconfiguration authority when the node is first connected to a network.\n\n The \"PORT_NAME\" defines the human-friendly name of the port, which is related to the corresponding function\n or a network service supported by the node. The name shall match the following POSIX ERE expression:\n\n [a-zA-Z_][a-zA-Z0-9_.]*\n\n The names are defined by the vendor of the node. The user/integrator is expected to understand their meaning and\n relation to the functional capabilities of the node by reading the technical documentation provided by the vendor.\n\n A port whose port-ID register is unset (invalid value) remains inactive (unused); the corresponding function may\n be disabled. For example, a register named \"uavcan.pub.measurement.id\" defines the subject-ID of a measurement\n published by this node; if the register contains an invalid value (above the maximum valid subject-ID),\n said measurement is not published.\n\n The same name is used in other similar registers defined below. Network introspection and autoconfiguration tools\n will expect to find a register of this form for every configurable port supported by the node.\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.pub.PORT_NAME.type string immutable, persistent N/A\n uavcan.sub.PORT_NAME.type ditto ditto ditto\n uavcan.cln.PORT_NAME.type ditto ditto ditto\n uavcan.srv.PORT_NAME.type ditto ditto ditto\n\n Publication/subscription/client/server full data type name and dot-separated version numbers, respectively.\n These registers are set by the vendor once and typically they are to remain unchanged (hence \"immutable\").\n The \"PORT_NAME\" defines the human-friendly name of the port as specified above.\n For example, a register named \"uavcan.pub.measurement.type\" may contain \"uavcan.si.sample.angle.Quaternion.1.0\".\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.diagnostic.*\n\n Prefix reserved for future use.\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.can.bitrate natural32[2] implementation-defined implementation-defined\n uavcan.can.iface string mutable, persistent implementation-defined\n\n These registers are only relevant for nodes that support Cyphal/CAN.\n\n uavcan.can.bitrate defines the CAN bus bit rate: the first value is the arbitration bit rate, the second is the\n data phase bit rate. Nodes that support only Classic CAN should ignore the second value. Nodes that support CAN FD\n should initialize in the Classic CAN mode (MTU 8 bytes, BRS flag not set) if the values are equal. If CAN bitrate\n is not configurable or is always auto-detected, this register may be omitted or made immutable; otherwise it should\n be mutable and persistent.\n\n uavcan.can.iface is only relevant for software nodes or nodes that are capable of using different CAN interfaces.\n The value is a space-separated list of CAN interface names to use. The name format is implementation-defined\n (for example, \"can0\").\n\n ---------------------------------------------------------------------------------------------------------------------\n\n uavcan.udp.*\n\n Prefix reserved for future use.\n\n ---------------------------------------------------------------------------------------------------------------------#\n\n uavcan.serial.*\n\n Prefix reserved for future use.\n\n ---------------------------------------------------------------------------------------------------------------------"
12452 )]
12453 pub struct AccessRequest {
12454 #[cfg_attr(
12455 not(doctest),
12456 doc = " The name of the accessed register. Shall not be empty.\n Use the List service to obtain the list of registers on the node."
12457 )]
12458 pub name: crate::uavcan::register::name_1_0::Name,
12464 #[cfg_attr(
12465 not(doctest),
12466 doc = " Value to be written. Empty if no write is required."
12467 )]
12468 pub value: crate::uavcan::register::value_1_0::Value,
12474 }
12475 impl ::emcyphal_encoding::DataType for AccessRequest {
12476 const EXTENT_BYTES: Option<u32> = None;
12478 }
12479 impl ::emcyphal_encoding::Request for AccessRequest {}
12480 impl ::emcyphal_encoding::BufferType for AccessRequest {
12481 type Buffer = ::emcyphal_encoding::StaticBuffer<515>;
12482 }
12483 impl AccessRequest {}
12484 impl ::emcyphal_encoding::Serialize for AccessRequest {
12485 fn size_bits(&self) -> usize {
12486 (self.name).size_bits() + (self.value).size_bits() + 0
12487 }
12488 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12489 cursor.write_composite(&self.name);
12490 cursor.write_composite(&self.value);
12491 }
12492 }
12493 impl ::emcyphal_encoding::Deserialize for AccessRequest {
12494 fn deserialize(
12495 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12496 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12497 where
12498 Self: Sized,
12499 {
12500 Ok(AccessRequest {
12501 name: { cursor.read_composite()? },
12502 value: { cursor.read_composite()? },
12503 })
12504 }
12505 }
12506
12507 pub struct AccessResponse {
12512 #[cfg_attr(
12513 not(doctest),
12514 doc = " The moment of time when the register was read (not written).\n Zero if the server does not support timestamping."
12515 )]
12516 pub timestamp:
12522 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
12523 #[cfg_attr(
12524 not(doctest),
12525 doc = " Mutable means that the register can be written using this service.\n Immutable registers cannot be written, but that doesn't imply that their values are constant (unchanging)."
12526 )]
12527 pub mutable: bool,
12533 #[cfg_attr(
12534 not(doctest),
12535 doc = " Persistence means that the register retains its value permanently across power cycles or any other changes\n in the state of the server, until it is explicitly overwritten (either via Cyphal, any other interface,\n or by the device itself).\n\n The server is recommended to manage persistence automatically by committing changed register values to a\n non-volatile storage automatically as necessary. If automatic persistence management is not implemented, it\n can be controlled manually via the standard service uavcan.node.ExecuteCommand. The same service can be used\n to return the configuration to a factory-default state. Please refer to its definition for more information.\n\n Consider the following examples:\n - Configuration parameters are usually both mutable and persistent.\n - Diagnostic values are usually immutable and non-persisient.\n - Registers that trigger an activity when written are typically mutable but non-persisient.\n - Registers that contain factory-programmed values such as calibration coefficients that can't\n be changed are typically immutable but persistent."
12536 )]
12537 pub persistent: bool,
12543 #[cfg_attr(
12545 not(doctest),
12546 doc = " The value of the register when it was read (beware of race conditions).\n Registers never change their type and dimensionality while the node is running.\n Empty value means that the register does not exist (in this case the flags should be cleared/ignored).\n By comparing the returned value against the write request the caller can determine whether the register\n was written successfully, unless write was not requested.\n An empty value shall never be returned for an existing register."
12547 )]
12548 pub value: crate::uavcan::register::value_1_0::Value,
12554 }
12555 impl ::emcyphal_encoding::DataType for AccessResponse {
12556 const EXTENT_BYTES: Option<u32> = None;
12558 }
12559 impl ::emcyphal_encoding::Response for AccessResponse {}
12560 impl ::emcyphal_encoding::BufferType for AccessResponse {
12561 type Buffer = ::emcyphal_encoding::StaticBuffer<267>;
12562 }
12563 impl AccessResponse {}
12564 impl ::emcyphal_encoding::Serialize for AccessResponse {
12565 fn size_bits(&self) -> usize {
12566 56 + 1 + 1 + 6 + (self.value).size_bits() + 0
12567 }
12568 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12569 cursor.write_composite(&self.timestamp);
12570 cursor.write_bool(self.mutable);
12571 cursor.write_bool(self.persistent);
12572 cursor.skip_6();
12573 cursor.write_composite(&self.value);
12574 }
12575 }
12576 impl ::emcyphal_encoding::Deserialize for AccessResponse {
12577 fn deserialize(
12578 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12579 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12580 where
12581 Self: Sized,
12582 {
12583 Ok(AccessResponse {
12584 timestamp: { cursor.read_composite()? },
12585 mutable: { cursor.read_bool() },
12586 persistent: { cursor.read_bool() },
12587 value: {
12588 cursor.skip_6();
12589 cursor.read_composite()?
12590 },
12591 })
12592 }
12593 }
12594 }
12595 pub mod list_1_0 {
12596 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
12597 pub const SERVICE: ::emcyphal_core::ServiceId =
12598 ::emcyphal_core::ServiceId::from_u16_truncating(385);
12599
12600 #[cfg_attr(
12605 not(doctest),
12606 doc = " This service allows the caller to discover the names of all registers available on the server\n by iterating the index field from zero until an empty name is returned.\n\n The ordering of the registers shall remain constant while the server is running.\n The ordering is not guaranteed to remain unchanged when the server node is restarted."
12607 )]
12608 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
12609 #[repr(C, packed)]
12610 pub struct ListRequest {
12611 pub index: u16,
12617 }
12618 impl ::emcyphal_encoding::DataType for ListRequest {
12619 const EXTENT_BYTES: Option<u32> = None;
12621 }
12622 impl ::emcyphal_encoding::Request for ListRequest {}
12623 impl ::emcyphal_encoding::BufferType for ListRequest {
12624 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
12625 }
12626 impl ListRequest {}
12627 impl ::emcyphal_encoding::Serialize for ListRequest {
12628 fn size_bits(&self) -> usize {
12629 16
12630 }
12631 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12632 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
12633 }
12634 }
12635 impl ::emcyphal_encoding::Deserialize for ListRequest {
12636 fn deserialize(
12637 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12638 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12639 where
12640 Self: Sized,
12641 {
12642 Ok(Self::deserialize_zero_copy(cursor))
12643 }
12644 }
12645 #[test]
12646 fn test_layout() {
12647 assert_eq!(::core::mem::size_of::<ListRequest>() * 8, 16);
12648 assert_eq!(::core::mem::offset_of!(ListRequest, index) * 8, 0);
12649 }
12650
12651 pub struct ListResponse {
12656 #[cfg_attr(
12657 not(doctest),
12658 doc = " Empty name in response means that the index is out of bounds, i.e., discovery is finished."
12659 )]
12660 pub name: crate::uavcan::register::name_1_0::Name,
12666 }
12667 impl ::emcyphal_encoding::DataType for ListResponse {
12668 const EXTENT_BYTES: Option<u32> = None;
12670 }
12671 impl ::emcyphal_encoding::Response for ListResponse {}
12672 impl ::emcyphal_encoding::BufferType for ListResponse {
12673 type Buffer = ::emcyphal_encoding::StaticBuffer<256>;
12674 }
12675 impl ListResponse {}
12676 impl ::emcyphal_encoding::Serialize for ListResponse {
12677 fn size_bits(&self) -> usize {
12678 (self.name).size_bits() + 0
12679 }
12680 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12681 cursor.write_composite(&self.name);
12682 }
12683 }
12684 impl ::emcyphal_encoding::Deserialize for ListResponse {
12685 fn deserialize(
12686 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12687 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12688 where
12689 Self: Sized,
12690 {
12691 Ok(ListResponse {
12692 name: { cursor.read_composite()? },
12693 })
12694 }
12695 }
12696 }
12697 pub mod name_1_0 {
12698 #[cfg_attr(not(doctest), doc = " An UTF8-encoded register name.")]
12703 pub struct Name {
12704 pub name: ::heapless::Vec<u8, 255>,
12710 }
12711 impl ::emcyphal_encoding::DataType for Name {
12712 const EXTENT_BYTES: Option<u32> = None;
12714 }
12715 impl ::emcyphal_encoding::Message for Name {}
12716 impl ::emcyphal_encoding::BufferType for Name {
12717 type Buffer = ::emcyphal_encoding::StaticBuffer<256>;
12718 }
12719 impl Name {}
12720 impl ::emcyphal_encoding::Serialize for Name {
12721 fn size_bits(&self) -> usize {
12722 8 + (self.name).len() * 8 + 0
12723 }
12724 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12725 cursor.write_aligned_u8((self.name).len() as u8);
12726 cursor.write_bytes(&(self.name)[..]);
12727 }
12728 }
12729 impl ::emcyphal_encoding::Deserialize for Name {
12730 fn deserialize(
12731 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12732 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12733 where
12734 Self: Sized,
12735 {
12736 Ok(Name {
12737 name: {
12738 let length = cursor.read_u8() as _;
12739 if length <= 255 {
12740 let mut elements = ::heapless::Vec::new();
12741 for _ in 0..length {
12742 let _ = elements.push(cursor.read_u8() as _);
12743 }
12744 elements
12745 } else {
12746 return Err(::emcyphal_encoding::DeserializeError::ArrayLength);
12747 }
12748 },
12749 })
12750 }
12751 }
12752 }
12753 pub mod value_1_0 {
12754 #[cfg_attr(
12759 not(doctest),
12760 doc = " This union contains all possible value types supported by the register protocol.\n Numeric types can be either scalars or arrays; the former is a special case of the latter."
12761 )]
12762 pub enum Value {
12763 #[cfg_attr(not(doctest), doc = " Tag 0 Used to represent an undefined value")]
12764 Empty(crate::uavcan::primitive::empty_1_0::Empty),
12767 #[cfg_attr(not(doctest), doc = " Tag 1 UTF-8 encoded text")]
12768 String(crate::uavcan::primitive::string_1_0::String),
12771 #[cfg_attr(not(doctest), doc = " Tag 2 Raw unstructured binary image")]
12772 Unstructured(crate::uavcan::primitive::unstructured_1_0::Unstructured),
12775 #[cfg_attr(not(doctest), doc = " Tag 3 Bit array")]
12776 Bit(crate::uavcan::primitive::array::bit_1_0::Bit),
12779 #[cfg_attr(not(doctest), doc = " Tag 4")]
12780 Integer64(crate::uavcan::primitive::array::integer64_1_0::Integer64),
12783 #[cfg_attr(not(doctest), doc = " Tag 5")]
12784 Integer32(crate::uavcan::primitive::array::integer32_1_0::Integer32),
12787 #[cfg_attr(not(doctest), doc = " Tag 6")]
12788 Integer16(crate::uavcan::primitive::array::integer16_1_0::Integer16),
12791 #[cfg_attr(not(doctest), doc = " Tag 7")]
12792 Integer8(crate::uavcan::primitive::array::integer8_1_0::Integer8),
12795 #[cfg_attr(not(doctest), doc = " Tag 8")]
12796 Natural64(crate::uavcan::primitive::array::natural64_1_0::Natural64),
12799 #[cfg_attr(not(doctest), doc = " Tag 9")]
12800 Natural32(crate::uavcan::primitive::array::natural32_1_0::Natural32),
12803 #[cfg_attr(not(doctest), doc = " Tag 10")]
12804 Natural16(crate::uavcan::primitive::array::natural16_1_0::Natural16),
12807 #[cfg_attr(not(doctest), doc = " Tag 11")]
12808 Natural8(crate::uavcan::primitive::array::natural8_1_0::Natural8),
12811 #[cfg_attr(
12812 not(doctest),
12813 doc = " Tag 12 Exactly representable integers: [-2**53, +2**53]"
12814 )]
12815 Real64(crate::uavcan::primitive::array::real64_1_0::Real64),
12818 #[cfg_attr(
12819 not(doctest),
12820 doc = " Tag 13 Exactly representable integers: [-16777216, +16777216]"
12821 )]
12822 Real32(crate::uavcan::primitive::array::real32_1_0::Real32),
12825 #[cfg_attr(
12826 not(doctest),
12827 doc = " Tag 14 Exactly representable integers: [-2048, +2048]\n Empty and the tag\n 258 bytes per field max and the tag"
12828 )]
12829 Real16(crate::uavcan::primitive::array::real16_1_0::Real16),
12832 }
12833 impl ::emcyphal_encoding::DataType for Value {
12834 const EXTENT_BYTES: Option<u32> = None;
12836 }
12837 impl ::emcyphal_encoding::Message for Value {}
12838 impl ::emcyphal_encoding::BufferType for Value {
12839 type Buffer = ::emcyphal_encoding::StaticBuffer<259>;
12840 }
12841 impl Value {}
12842 impl ::emcyphal_encoding::Serialize for Value {
12843 fn size_bits(&self) -> usize {
12844 8 + match self {
12845 Value::Empty(inner) => 0,
12846 Value::String(inner) => (inner).size_bits(),
12847 Value::Unstructured(inner) => (inner).size_bits(),
12848 Value::Bit(inner) => (inner).size_bits(),
12849 Value::Integer64(inner) => (inner).size_bits(),
12850 Value::Integer32(inner) => (inner).size_bits(),
12851 Value::Integer16(inner) => (inner).size_bits(),
12852 Value::Integer8(inner) => (inner).size_bits(),
12853 Value::Natural64(inner) => (inner).size_bits(),
12854 Value::Natural32(inner) => (inner).size_bits(),
12855 Value::Natural16(inner) => (inner).size_bits(),
12856 Value::Natural8(inner) => (inner).size_bits(),
12857 Value::Real64(inner) => (inner).size_bits(),
12858 Value::Real32(inner) => (inner).size_bits(),
12859 Value::Real16(inner) => (inner).size_bits(),
12860 }
12861 }
12862 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12863 match self {
12864 Value::Empty(inner) => {
12865 cursor.write_aligned_u8(0);
12866 cursor.write_composite(inner);
12867 }
12868 Value::String(inner) => {
12869 cursor.write_aligned_u8(1);
12870 cursor.write_composite(inner);
12871 }
12872 Value::Unstructured(inner) => {
12873 cursor.write_aligned_u8(2);
12874 cursor.write_composite(inner);
12875 }
12876 Value::Bit(inner) => {
12877 cursor.write_aligned_u8(3);
12878 cursor.write_composite(inner);
12879 }
12880 Value::Integer64(inner) => {
12881 cursor.write_aligned_u8(4);
12882 cursor.write_composite(inner);
12883 }
12884 Value::Integer32(inner) => {
12885 cursor.write_aligned_u8(5);
12886 cursor.write_composite(inner);
12887 }
12888 Value::Integer16(inner) => {
12889 cursor.write_aligned_u8(6);
12890 cursor.write_composite(inner);
12891 }
12892 Value::Integer8(inner) => {
12893 cursor.write_aligned_u8(7);
12894 cursor.write_composite(inner);
12895 }
12896 Value::Natural64(inner) => {
12897 cursor.write_aligned_u8(8);
12898 cursor.write_composite(inner);
12899 }
12900 Value::Natural32(inner) => {
12901 cursor.write_aligned_u8(9);
12902 cursor.write_composite(inner);
12903 }
12904 Value::Natural16(inner) => {
12905 cursor.write_aligned_u8(10);
12906 cursor.write_composite(inner);
12907 }
12908 Value::Natural8(inner) => {
12909 cursor.write_aligned_u8(11);
12910 cursor.write_composite(inner);
12911 }
12912 Value::Real64(inner) => {
12913 cursor.write_aligned_u8(12);
12914 cursor.write_composite(inner);
12915 }
12916 Value::Real32(inner) => {
12917 cursor.write_aligned_u8(13);
12918 cursor.write_composite(inner);
12919 }
12920 Value::Real16(inner) => {
12921 cursor.write_aligned_u8(14);
12922 cursor.write_composite(inner);
12923 }
12924 }
12925 }
12926 }
12927 impl ::emcyphal_encoding::Deserialize for Value {
12928 fn deserialize(
12929 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
12930 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
12931 where
12932 Self: Sized,
12933 {
12934 match cursor.read_aligned_u8() as _ {
12935 0 => Ok(Value::Empty({ cursor.read_composite()? })),
12936 1 => Ok(Value::String({ cursor.read_composite()? })),
12937 2 => Ok(Value::Unstructured({ cursor.read_composite()? })),
12938 3 => Ok(Value::Bit({ cursor.read_composite()? })),
12939 4 => Ok(Value::Integer64({ cursor.read_composite()? })),
12940 5 => Ok(Value::Integer32({ cursor.read_composite()? })),
12941 6 => Ok(Value::Integer16({ cursor.read_composite()? })),
12942 7 => Ok(Value::Integer8({ cursor.read_composite()? })),
12943 8 => Ok(Value::Natural64({ cursor.read_composite()? })),
12944 9 => Ok(Value::Natural32({ cursor.read_composite()? })),
12945 10 => Ok(Value::Natural16({ cursor.read_composite()? })),
12946 11 => Ok(Value::Natural8({ cursor.read_composite()? })),
12947 12 => Ok(Value::Real64({ cursor.read_composite()? })),
12948 13 => Ok(Value::Real32({ cursor.read_composite()? })),
12949 14 => Ok(Value::Real16({ cursor.read_composite()? })),
12950 _ => Err(::emcyphal_encoding::DeserializeError::UnionTag),
12951 }
12952 }
12953 }
12954 }
12955 }
12956 pub mod si {
12957 pub mod sample {
12958 pub mod acceleration {
12959 pub mod scalar_1_0 {
12960 pub struct Scalar {
12965 pub timestamp:
12971 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
12972 pub meter_per_second_per_second: f32,
12978 }
12979 impl ::emcyphal_encoding::DataType for Scalar {
12980 const EXTENT_BYTES: Option<u32> = None;
12982 }
12983 impl ::emcyphal_encoding::Message for Scalar {}
12984 impl ::emcyphal_encoding::BufferType for Scalar {
12985 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
12986 }
12987 impl Scalar {}
12988 impl ::emcyphal_encoding::Serialize for Scalar {
12989 fn size_bits(&self) -> usize {
12990 88
12991 }
12992 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
12993 cursor.write_composite(&self.timestamp);
12994 cursor.write_f32(self.meter_per_second_per_second);
12995 }
12996 }
12997 impl ::emcyphal_encoding::Deserialize for Scalar {
12998 fn deserialize(
12999 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13000 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13001 where
13002 Self: Sized,
13003 {
13004 Ok(Scalar {
13005 timestamp: { cursor.read_composite()? },
13006 meter_per_second_per_second: { cursor.read_f32() },
13007 })
13008 }
13009 }
13010 }
13011 pub mod vector3_1_0 {
13012 pub struct Vector3 {
13017 pub timestamp:
13023 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13024 pub meter_per_second_per_second: [f32; 3],
13030 }
13031 impl ::emcyphal_encoding::DataType for Vector3 {
13032 const EXTENT_BYTES: Option<u32> = None;
13034 }
13035 impl ::emcyphal_encoding::Message for Vector3 {}
13036 impl ::emcyphal_encoding::BufferType for Vector3 {
13037 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
13038 }
13039 impl Vector3 {}
13040 impl ::emcyphal_encoding::Serialize for Vector3 {
13041 fn size_bits(&self) -> usize {
13042 152
13043 }
13044 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13045 cursor.write_composite(&self.timestamp);
13046 for value in (self.meter_per_second_per_second).iter() {
13047 cursor.write_f32(*value);
13048 }
13049 }
13050 }
13051 impl ::emcyphal_encoding::Deserialize for Vector3 {
13052 fn deserialize(
13053 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13054 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13055 where
13056 Self: Sized,
13057 {
13058 Ok(Vector3 {
13059 timestamp: { cursor.read_composite()? },
13060 meter_per_second_per_second: {
13061 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
13062 },
13063 })
13064 }
13065 }
13066 }
13067 }
13068 pub mod angle {
13069 pub mod narrow_scalar_1_0 {
13070 pub struct NarrowScalar {
13075 pub timestamp:
13081 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13082 pub radian: ::half::f16,
13088 }
13089 impl ::emcyphal_encoding::DataType for NarrowScalar {
13090 const EXTENT_BYTES: Option<u32> = None;
13092 }
13093 impl ::emcyphal_encoding::Message for NarrowScalar {}
13094 impl ::emcyphal_encoding::BufferType for NarrowScalar {
13095 type Buffer = ::emcyphal_encoding::StaticBuffer<9>;
13096 }
13097 impl NarrowScalar {}
13098 impl ::emcyphal_encoding::Serialize for NarrowScalar {
13099 fn size_bits(&self) -> usize {
13100 72
13101 }
13102 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13103 cursor.write_composite(&self.timestamp);
13104 cursor.write_f16(self.radian);
13105 }
13106 }
13107 impl ::emcyphal_encoding::Deserialize for NarrowScalar {
13108 fn deserialize(
13109 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13110 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13111 where
13112 Self: Sized,
13113 {
13114 Ok(NarrowScalar {
13115 timestamp: { cursor.read_composite()? },
13116 radian: { cursor.read_f16() },
13117 })
13118 }
13119 }
13120 }
13121 pub mod narrow_vector3_1_0 {
13122 pub struct NarrowVector3 {
13127 pub timestamp:
13133 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13134 pub radian: [::half::f16; 3],
13140 }
13141 impl ::emcyphal_encoding::DataType for NarrowVector3 {
13142 const EXTENT_BYTES: Option<u32> = None;
13144 }
13145 impl ::emcyphal_encoding::Message for NarrowVector3 {}
13146 impl ::emcyphal_encoding::BufferType for NarrowVector3 {
13147 type Buffer = ::emcyphal_encoding::StaticBuffer<13>;
13148 }
13149 impl NarrowVector3 {}
13150 impl ::emcyphal_encoding::Serialize for NarrowVector3 {
13151 fn size_bits(&self) -> usize {
13152 104
13153 }
13154 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13155 cursor.write_composite(&self.timestamp);
13156 for value in (self.radian).iter() {
13157 cursor.write_f16(*value);
13158 }
13159 }
13160 }
13161 impl ::emcyphal_encoding::Deserialize for NarrowVector3 {
13162 fn deserialize(
13163 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13164 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13165 where
13166 Self: Sized,
13167 {
13168 Ok(NarrowVector3 {
13169 timestamp: { cursor.read_composite()? },
13170 radian: {
13171 [cursor.read_f16(), cursor.read_f16(), cursor.read_f16()]
13172 },
13173 })
13174 }
13175 }
13176 }
13177 pub mod quaternion_1_0 {
13178 pub struct Quaternion {
13183 pub timestamp:
13189 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13190 pub wxyz: [f32; 4],
13196 }
13197 impl ::emcyphal_encoding::DataType for Quaternion {
13198 const EXTENT_BYTES: Option<u32> = None;
13200 }
13201 impl ::emcyphal_encoding::Message for Quaternion {}
13202 impl ::emcyphal_encoding::BufferType for Quaternion {
13203 type Buffer = ::emcyphal_encoding::StaticBuffer<23>;
13204 }
13205 impl Quaternion {}
13206 impl ::emcyphal_encoding::Serialize for Quaternion {
13207 fn size_bits(&self) -> usize {
13208 184
13209 }
13210 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13211 cursor.write_composite(&self.timestamp);
13212 for value in (self.wxyz).iter() {
13213 cursor.write_f32(*value);
13214 }
13215 }
13216 }
13217 impl ::emcyphal_encoding::Deserialize for Quaternion {
13218 fn deserialize(
13219 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13220 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13221 where
13222 Self: Sized,
13223 {
13224 Ok(Quaternion {
13225 timestamp: { cursor.read_composite()? },
13226 wxyz: {
13227 [
13228 cursor.read_f32(),
13229 cursor.read_f32(),
13230 cursor.read_f32(),
13231 cursor.read_f32(),
13232 ]
13233 },
13234 })
13235 }
13236 }
13237 }
13238 pub mod scalar_1_0 {
13239 pub struct Scalar {
13244 pub timestamp:
13250 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13251 pub radian: f32,
13257 }
13258 impl ::emcyphal_encoding::DataType for Scalar {
13259 const EXTENT_BYTES: Option<u32> = None;
13261 }
13262 impl ::emcyphal_encoding::Message for Scalar {}
13263 impl ::emcyphal_encoding::BufferType for Scalar {
13264 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13265 }
13266 impl Scalar {}
13267 impl ::emcyphal_encoding::Serialize for Scalar {
13268 fn size_bits(&self) -> usize {
13269 88
13270 }
13271 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13272 cursor.write_composite(&self.timestamp);
13273 cursor.write_f32(self.radian);
13274 }
13275 }
13276 impl ::emcyphal_encoding::Deserialize for Scalar {
13277 fn deserialize(
13278 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13279 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13280 where
13281 Self: Sized,
13282 {
13283 Ok(Scalar {
13284 timestamp: { cursor.read_composite()? },
13285 radian: { cursor.read_f32() },
13286 })
13287 }
13288 }
13289 }
13290 pub mod vector3_1_0 {
13291 pub struct Vector3 {
13296 pub timestamp:
13302 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13303 pub radian: [f32; 3],
13309 }
13310 impl ::emcyphal_encoding::DataType for Vector3 {
13311 const EXTENT_BYTES: Option<u32> = None;
13313 }
13314 impl ::emcyphal_encoding::Message for Vector3 {}
13315 impl ::emcyphal_encoding::BufferType for Vector3 {
13316 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
13317 }
13318 impl Vector3 {}
13319 impl ::emcyphal_encoding::Serialize for Vector3 {
13320 fn size_bits(&self) -> usize {
13321 152
13322 }
13323 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13324 cursor.write_composite(&self.timestamp);
13325 for value in (self.radian).iter() {
13326 cursor.write_f32(*value);
13327 }
13328 }
13329 }
13330 impl ::emcyphal_encoding::Deserialize for Vector3 {
13331 fn deserialize(
13332 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13333 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13334 where
13335 Self: Sized,
13336 {
13337 Ok(Vector3 {
13338 timestamp: { cursor.read_composite()? },
13339 radian: {
13340 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
13341 },
13342 })
13343 }
13344 }
13345 }
13346 pub mod wide_scalar_1_0 {
13347 pub struct WideScalar {
13352 pub timestamp:
13358 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13359 pub radian: f64,
13365 }
13366 impl ::emcyphal_encoding::DataType for WideScalar {
13367 const EXTENT_BYTES: Option<u32> = None;
13369 }
13370 impl ::emcyphal_encoding::Message for WideScalar {}
13371 impl ::emcyphal_encoding::BufferType for WideScalar {
13372 type Buffer = ::emcyphal_encoding::StaticBuffer<15>;
13373 }
13374 impl WideScalar {}
13375 impl ::emcyphal_encoding::Serialize for WideScalar {
13376 fn size_bits(&self) -> usize {
13377 120
13378 }
13379 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13380 cursor.write_composite(&self.timestamp);
13381 cursor.write_f64(self.radian);
13382 }
13383 }
13384 impl ::emcyphal_encoding::Deserialize for WideScalar {
13385 fn deserialize(
13386 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13387 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13388 where
13389 Self: Sized,
13390 {
13391 Ok(WideScalar {
13392 timestamp: { cursor.read_composite()? },
13393 radian: { cursor.read_f64() },
13394 })
13395 }
13396 }
13397 }
13398 pub mod wide_vector3_1_0 {
13399 pub struct WideVector3 {
13404 pub timestamp:
13410 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13411 pub radian: [f64; 3],
13417 }
13418 impl ::emcyphal_encoding::DataType for WideVector3 {
13419 const EXTENT_BYTES: Option<u32> = None;
13421 }
13422 impl ::emcyphal_encoding::Message for WideVector3 {}
13423 impl ::emcyphal_encoding::BufferType for WideVector3 {
13424 type Buffer = ::emcyphal_encoding::StaticBuffer<31>;
13425 }
13426 impl WideVector3 {}
13427 impl ::emcyphal_encoding::Serialize for WideVector3 {
13428 fn size_bits(&self) -> usize {
13429 248
13430 }
13431 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13432 cursor.write_composite(&self.timestamp);
13433 for value in (self.radian).iter() {
13434 cursor.write_f64(*value);
13435 }
13436 }
13437 }
13438 impl ::emcyphal_encoding::Deserialize for WideVector3 {
13439 fn deserialize(
13440 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13441 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13442 where
13443 Self: Sized,
13444 {
13445 Ok(WideVector3 {
13446 timestamp: { cursor.read_composite()? },
13447 radian: {
13448 [cursor.read_f64(), cursor.read_f64(), cursor.read_f64()]
13449 },
13450 })
13451 }
13452 }
13453 }
13454 }
13455 pub mod angular_acceleration {
13456 pub mod scalar_1_0 {
13457 pub struct Scalar {
13462 pub timestamp:
13468 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13469 pub radian_per_second_per_second: f32,
13475 }
13476 impl ::emcyphal_encoding::DataType for Scalar {
13477 const EXTENT_BYTES: Option<u32> = None;
13479 }
13480 impl ::emcyphal_encoding::Message for Scalar {}
13481 impl ::emcyphal_encoding::BufferType for Scalar {
13482 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13483 }
13484 impl Scalar {}
13485 impl ::emcyphal_encoding::Serialize for Scalar {
13486 fn size_bits(&self) -> usize {
13487 88
13488 }
13489 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13490 cursor.write_composite(&self.timestamp);
13491 cursor.write_f32(self.radian_per_second_per_second);
13492 }
13493 }
13494 impl ::emcyphal_encoding::Deserialize for Scalar {
13495 fn deserialize(
13496 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13497 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13498 where
13499 Self: Sized,
13500 {
13501 Ok(Scalar {
13502 timestamp: { cursor.read_composite()? },
13503 radian_per_second_per_second: { cursor.read_f32() },
13504 })
13505 }
13506 }
13507 }
13508 pub mod vector3_1_0 {
13509 pub struct Vector3 {
13514 pub timestamp:
13520 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13521 pub radian_per_second_per_second: [f32; 3],
13527 }
13528 impl ::emcyphal_encoding::DataType for Vector3 {
13529 const EXTENT_BYTES: Option<u32> = None;
13531 }
13532 impl ::emcyphal_encoding::Message for Vector3 {}
13533 impl ::emcyphal_encoding::BufferType for Vector3 {
13534 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
13535 }
13536 impl Vector3 {}
13537 impl ::emcyphal_encoding::Serialize for Vector3 {
13538 fn size_bits(&self) -> usize {
13539 152
13540 }
13541 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13542 cursor.write_composite(&self.timestamp);
13543 for value in (self.radian_per_second_per_second).iter() {
13544 cursor.write_f32(*value);
13545 }
13546 }
13547 }
13548 impl ::emcyphal_encoding::Deserialize for Vector3 {
13549 fn deserialize(
13550 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13551 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13552 where
13553 Self: Sized,
13554 {
13555 Ok(Vector3 {
13556 timestamp: { cursor.read_composite()? },
13557 radian_per_second_per_second: {
13558 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
13559 },
13560 })
13561 }
13562 }
13563 }
13564 }
13565 pub mod angular_velocity {
13566 pub mod scalar_1_0 {
13567 pub struct Scalar {
13572 pub timestamp:
13578 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13579 pub radian_per_second: f32,
13585 }
13586 impl ::emcyphal_encoding::DataType for Scalar {
13587 const EXTENT_BYTES: Option<u32> = None;
13589 }
13590 impl ::emcyphal_encoding::Message for Scalar {}
13591 impl ::emcyphal_encoding::BufferType for Scalar {
13592 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13593 }
13594 impl Scalar {}
13595 impl ::emcyphal_encoding::Serialize for Scalar {
13596 fn size_bits(&self) -> usize {
13597 88
13598 }
13599 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13600 cursor.write_composite(&self.timestamp);
13601 cursor.write_f32(self.radian_per_second);
13602 }
13603 }
13604 impl ::emcyphal_encoding::Deserialize for Scalar {
13605 fn deserialize(
13606 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13607 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13608 where
13609 Self: Sized,
13610 {
13611 Ok(Scalar {
13612 timestamp: { cursor.read_composite()? },
13613 radian_per_second: { cursor.read_f32() },
13614 })
13615 }
13616 }
13617 }
13618 pub mod vector3_1_0 {
13619 pub struct Vector3 {
13624 pub timestamp:
13630 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13631 pub radian_per_second: [f32; 3],
13637 }
13638 impl ::emcyphal_encoding::DataType for Vector3 {
13639 const EXTENT_BYTES: Option<u32> = None;
13641 }
13642 impl ::emcyphal_encoding::Message for Vector3 {}
13643 impl ::emcyphal_encoding::BufferType for Vector3 {
13644 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
13645 }
13646 impl Vector3 {}
13647 impl ::emcyphal_encoding::Serialize for Vector3 {
13648 fn size_bits(&self) -> usize {
13649 152
13650 }
13651 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13652 cursor.write_composite(&self.timestamp);
13653 for value in (self.radian_per_second).iter() {
13654 cursor.write_f32(*value);
13655 }
13656 }
13657 }
13658 impl ::emcyphal_encoding::Deserialize for Vector3 {
13659 fn deserialize(
13660 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13661 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13662 where
13663 Self: Sized,
13664 {
13665 Ok(Vector3 {
13666 timestamp: { cursor.read_composite()? },
13667 radian_per_second: {
13668 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
13669 },
13670 })
13671 }
13672 }
13673 }
13674 }
13675 pub mod duration {
13676 pub mod scalar_1_0 {
13677 pub struct Scalar {
13682 pub timestamp:
13688 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13689 pub second: f32,
13695 }
13696 impl ::emcyphal_encoding::DataType for Scalar {
13697 const EXTENT_BYTES: Option<u32> = None;
13699 }
13700 impl ::emcyphal_encoding::Message for Scalar {}
13701 impl ::emcyphal_encoding::BufferType for Scalar {
13702 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13703 }
13704 impl Scalar {}
13705 impl ::emcyphal_encoding::Serialize for Scalar {
13706 fn size_bits(&self) -> usize {
13707 88
13708 }
13709 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13710 cursor.write_composite(&self.timestamp);
13711 cursor.write_f32(self.second);
13712 }
13713 }
13714 impl ::emcyphal_encoding::Deserialize for Scalar {
13715 fn deserialize(
13716 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13717 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13718 where
13719 Self: Sized,
13720 {
13721 Ok(Scalar {
13722 timestamp: { cursor.read_composite()? },
13723 second: { cursor.read_f32() },
13724 })
13725 }
13726 }
13727 }
13728 pub mod wide_scalar_1_0 {
13729 pub struct WideScalar {
13734 pub timestamp:
13740 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13741 pub second: f64,
13747 }
13748 impl ::emcyphal_encoding::DataType for WideScalar {
13749 const EXTENT_BYTES: Option<u32> = None;
13751 }
13752 impl ::emcyphal_encoding::Message for WideScalar {}
13753 impl ::emcyphal_encoding::BufferType for WideScalar {
13754 type Buffer = ::emcyphal_encoding::StaticBuffer<15>;
13755 }
13756 impl WideScalar {}
13757 impl ::emcyphal_encoding::Serialize for WideScalar {
13758 fn size_bits(&self) -> usize {
13759 120
13760 }
13761 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13762 cursor.write_composite(&self.timestamp);
13763 cursor.write_f64(self.second);
13764 }
13765 }
13766 impl ::emcyphal_encoding::Deserialize for WideScalar {
13767 fn deserialize(
13768 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13769 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13770 where
13771 Self: Sized,
13772 {
13773 Ok(WideScalar {
13774 timestamp: { cursor.read_composite()? },
13775 second: { cursor.read_f64() },
13776 })
13777 }
13778 }
13779 }
13780 }
13781 pub mod electric_charge {
13782 pub mod scalar_1_0 {
13783 pub struct Scalar {
13788 pub timestamp:
13794 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13795 pub coulomb: f32,
13801 }
13802 impl ::emcyphal_encoding::DataType for Scalar {
13803 const EXTENT_BYTES: Option<u32> = None;
13805 }
13806 impl ::emcyphal_encoding::Message for Scalar {}
13807 impl ::emcyphal_encoding::BufferType for Scalar {
13808 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13809 }
13810 impl Scalar {}
13811 impl ::emcyphal_encoding::Serialize for Scalar {
13812 fn size_bits(&self) -> usize {
13813 88
13814 }
13815 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13816 cursor.write_composite(&self.timestamp);
13817 cursor.write_f32(self.coulomb);
13818 }
13819 }
13820 impl ::emcyphal_encoding::Deserialize for Scalar {
13821 fn deserialize(
13822 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13823 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13824 where
13825 Self: Sized,
13826 {
13827 Ok(Scalar {
13828 timestamp: { cursor.read_composite()? },
13829 coulomb: { cursor.read_f32() },
13830 })
13831 }
13832 }
13833 }
13834 }
13835 pub mod electric_current {
13836 pub mod scalar_1_0 {
13837 pub struct Scalar {
13842 pub timestamp:
13848 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13849 pub ampere: f32,
13855 }
13856 impl ::emcyphal_encoding::DataType for Scalar {
13857 const EXTENT_BYTES: Option<u32> = None;
13859 }
13860 impl ::emcyphal_encoding::Message for Scalar {}
13861 impl ::emcyphal_encoding::BufferType for Scalar {
13862 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13863 }
13864 impl Scalar {}
13865 impl ::emcyphal_encoding::Serialize for Scalar {
13866 fn size_bits(&self) -> usize {
13867 88
13868 }
13869 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13870 cursor.write_composite(&self.timestamp);
13871 cursor.write_f32(self.ampere);
13872 }
13873 }
13874 impl ::emcyphal_encoding::Deserialize for Scalar {
13875 fn deserialize(
13876 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13877 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13878 where
13879 Self: Sized,
13880 {
13881 Ok(Scalar {
13882 timestamp: { cursor.read_composite()? },
13883 ampere: { cursor.read_f32() },
13884 })
13885 }
13886 }
13887 }
13888 }
13889 pub mod energy {
13890 pub mod scalar_1_0 {
13891 pub struct Scalar {
13896 pub timestamp:
13902 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13903 pub joule: f32,
13909 }
13910 impl ::emcyphal_encoding::DataType for Scalar {
13911 const EXTENT_BYTES: Option<u32> = None;
13913 }
13914 impl ::emcyphal_encoding::Message for Scalar {}
13915 impl ::emcyphal_encoding::BufferType for Scalar {
13916 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13917 }
13918 impl Scalar {}
13919 impl ::emcyphal_encoding::Serialize for Scalar {
13920 fn size_bits(&self) -> usize {
13921 88
13922 }
13923 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13924 cursor.write_composite(&self.timestamp);
13925 cursor.write_f32(self.joule);
13926 }
13927 }
13928 impl ::emcyphal_encoding::Deserialize for Scalar {
13929 fn deserialize(
13930 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13931 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13932 where
13933 Self: Sized,
13934 {
13935 Ok(Scalar {
13936 timestamp: { cursor.read_composite()? },
13937 joule: { cursor.read_f32() },
13938 })
13939 }
13940 }
13941 }
13942 }
13943 pub mod force {
13944 pub mod scalar_1_0 {
13945 pub struct Scalar {
13950 pub timestamp:
13956 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
13957 pub newton: f32,
13963 }
13964 impl ::emcyphal_encoding::DataType for Scalar {
13965 const EXTENT_BYTES: Option<u32> = None;
13967 }
13968 impl ::emcyphal_encoding::Message for Scalar {}
13969 impl ::emcyphal_encoding::BufferType for Scalar {
13970 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
13971 }
13972 impl Scalar {}
13973 impl ::emcyphal_encoding::Serialize for Scalar {
13974 fn size_bits(&self) -> usize {
13975 88
13976 }
13977 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
13978 cursor.write_composite(&self.timestamp);
13979 cursor.write_f32(self.newton);
13980 }
13981 }
13982 impl ::emcyphal_encoding::Deserialize for Scalar {
13983 fn deserialize(
13984 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
13985 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
13986 where
13987 Self: Sized,
13988 {
13989 Ok(Scalar {
13990 timestamp: { cursor.read_composite()? },
13991 newton: { cursor.read_f32() },
13992 })
13993 }
13994 }
13995 }
13996 pub mod vector3_1_0 {
13997 pub struct Vector3 {
14002 pub timestamp:
14008 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14009 pub newton: [f32; 3],
14015 }
14016 impl ::emcyphal_encoding::DataType for Vector3 {
14017 const EXTENT_BYTES: Option<u32> = None;
14019 }
14020 impl ::emcyphal_encoding::Message for Vector3 {}
14021 impl ::emcyphal_encoding::BufferType for Vector3 {
14022 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
14023 }
14024 impl Vector3 {}
14025 impl ::emcyphal_encoding::Serialize for Vector3 {
14026 fn size_bits(&self) -> usize {
14027 152
14028 }
14029 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14030 cursor.write_composite(&self.timestamp);
14031 for value in (self.newton).iter() {
14032 cursor.write_f32(*value);
14033 }
14034 }
14035 }
14036 impl ::emcyphal_encoding::Deserialize for Vector3 {
14037 fn deserialize(
14038 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14039 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14040 where
14041 Self: Sized,
14042 {
14043 Ok(Vector3 {
14044 timestamp: { cursor.read_composite()? },
14045 newton: {
14046 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
14047 },
14048 })
14049 }
14050 }
14051 }
14052 }
14053 pub mod frequency {
14054 pub mod scalar_1_0 {
14055 pub struct Scalar {
14060 pub timestamp:
14066 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14067 pub hertz: f32,
14073 }
14074 impl ::emcyphal_encoding::DataType for Scalar {
14075 const EXTENT_BYTES: Option<u32> = None;
14077 }
14078 impl ::emcyphal_encoding::Message for Scalar {}
14079 impl ::emcyphal_encoding::BufferType for Scalar {
14080 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14081 }
14082 impl Scalar {}
14083 impl ::emcyphal_encoding::Serialize for Scalar {
14084 fn size_bits(&self) -> usize {
14085 88
14086 }
14087 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14088 cursor.write_composite(&self.timestamp);
14089 cursor.write_f32(self.hertz);
14090 }
14091 }
14092 impl ::emcyphal_encoding::Deserialize for Scalar {
14093 fn deserialize(
14094 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14095 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14096 where
14097 Self: Sized,
14098 {
14099 Ok(Scalar {
14100 timestamp: { cursor.read_composite()? },
14101 hertz: { cursor.read_f32() },
14102 })
14103 }
14104 }
14105 }
14106 }
14107 pub mod length {
14108 pub mod narrow_scalar_1_0 {
14109 pub struct NarrowScalar {
14114 pub timestamp:
14120 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14121 pub meter: ::half::f16,
14127 }
14128 impl ::emcyphal_encoding::DataType for NarrowScalar {
14129 const EXTENT_BYTES: Option<u32> = None;
14131 }
14132 impl ::emcyphal_encoding::Message for NarrowScalar {}
14133 impl ::emcyphal_encoding::BufferType for NarrowScalar {
14134 type Buffer = ::emcyphal_encoding::StaticBuffer<9>;
14135 }
14136 impl NarrowScalar {}
14137 impl ::emcyphal_encoding::Serialize for NarrowScalar {
14138 fn size_bits(&self) -> usize {
14139 72
14140 }
14141 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14142 cursor.write_composite(&self.timestamp);
14143 cursor.write_f16(self.meter);
14144 }
14145 }
14146 impl ::emcyphal_encoding::Deserialize for NarrowScalar {
14147 fn deserialize(
14148 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14149 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14150 where
14151 Self: Sized,
14152 {
14153 Ok(NarrowScalar {
14154 timestamp: { cursor.read_composite()? },
14155 meter: { cursor.read_f16() },
14156 })
14157 }
14158 }
14159 }
14160 pub mod narrow_vector3_1_0 {
14161 pub struct NarrowVector3 {
14166 pub timestamp:
14172 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14173 pub meter: [::half::f16; 3],
14179 }
14180 impl ::emcyphal_encoding::DataType for NarrowVector3 {
14181 const EXTENT_BYTES: Option<u32> = None;
14183 }
14184 impl ::emcyphal_encoding::Message for NarrowVector3 {}
14185 impl ::emcyphal_encoding::BufferType for NarrowVector3 {
14186 type Buffer = ::emcyphal_encoding::StaticBuffer<13>;
14187 }
14188 impl NarrowVector3 {}
14189 impl ::emcyphal_encoding::Serialize for NarrowVector3 {
14190 fn size_bits(&self) -> usize {
14191 104
14192 }
14193 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14194 cursor.write_composite(&self.timestamp);
14195 for value in (self.meter).iter() {
14196 cursor.write_f16(*value);
14197 }
14198 }
14199 }
14200 impl ::emcyphal_encoding::Deserialize for NarrowVector3 {
14201 fn deserialize(
14202 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14203 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14204 where
14205 Self: Sized,
14206 {
14207 Ok(NarrowVector3 {
14208 timestamp: { cursor.read_composite()? },
14209 meter: {
14210 [cursor.read_f16(), cursor.read_f16(), cursor.read_f16()]
14211 },
14212 })
14213 }
14214 }
14215 }
14216 pub mod scalar_1_0 {
14217 pub struct Scalar {
14222 pub timestamp:
14228 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14229 pub meter: f32,
14235 }
14236 impl ::emcyphal_encoding::DataType for Scalar {
14237 const EXTENT_BYTES: Option<u32> = None;
14239 }
14240 impl ::emcyphal_encoding::Message for Scalar {}
14241 impl ::emcyphal_encoding::BufferType for Scalar {
14242 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14243 }
14244 impl Scalar {}
14245 impl ::emcyphal_encoding::Serialize for Scalar {
14246 fn size_bits(&self) -> usize {
14247 88
14248 }
14249 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14250 cursor.write_composite(&self.timestamp);
14251 cursor.write_f32(self.meter);
14252 }
14253 }
14254 impl ::emcyphal_encoding::Deserialize for Scalar {
14255 fn deserialize(
14256 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14257 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14258 where
14259 Self: Sized,
14260 {
14261 Ok(Scalar {
14262 timestamp: { cursor.read_composite()? },
14263 meter: { cursor.read_f32() },
14264 })
14265 }
14266 }
14267 }
14268 pub mod vector3_1_0 {
14269 pub struct Vector3 {
14274 pub timestamp:
14280 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14281 pub meter: [f32; 3],
14287 }
14288 impl ::emcyphal_encoding::DataType for Vector3 {
14289 const EXTENT_BYTES: Option<u32> = None;
14291 }
14292 impl ::emcyphal_encoding::Message for Vector3 {}
14293 impl ::emcyphal_encoding::BufferType for Vector3 {
14294 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
14295 }
14296 impl Vector3 {}
14297 impl ::emcyphal_encoding::Serialize for Vector3 {
14298 fn size_bits(&self) -> usize {
14299 152
14300 }
14301 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14302 cursor.write_composite(&self.timestamp);
14303 for value in (self.meter).iter() {
14304 cursor.write_f32(*value);
14305 }
14306 }
14307 }
14308 impl ::emcyphal_encoding::Deserialize for Vector3 {
14309 fn deserialize(
14310 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14311 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14312 where
14313 Self: Sized,
14314 {
14315 Ok(Vector3 {
14316 timestamp: { cursor.read_composite()? },
14317 meter: {
14318 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
14319 },
14320 })
14321 }
14322 }
14323 }
14324 pub mod wide_scalar_1_0 {
14325 pub struct WideScalar {
14330 pub timestamp:
14336 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14337 pub meter: f64,
14343 }
14344 impl ::emcyphal_encoding::DataType for WideScalar {
14345 const EXTENT_BYTES: Option<u32> = None;
14347 }
14348 impl ::emcyphal_encoding::Message for WideScalar {}
14349 impl ::emcyphal_encoding::BufferType for WideScalar {
14350 type Buffer = ::emcyphal_encoding::StaticBuffer<15>;
14351 }
14352 impl WideScalar {}
14353 impl ::emcyphal_encoding::Serialize for WideScalar {
14354 fn size_bits(&self) -> usize {
14355 120
14356 }
14357 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14358 cursor.write_composite(&self.timestamp);
14359 cursor.write_f64(self.meter);
14360 }
14361 }
14362 impl ::emcyphal_encoding::Deserialize for WideScalar {
14363 fn deserialize(
14364 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14365 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14366 where
14367 Self: Sized,
14368 {
14369 Ok(WideScalar {
14370 timestamp: { cursor.read_composite()? },
14371 meter: { cursor.read_f64() },
14372 })
14373 }
14374 }
14375 }
14376 pub mod wide_vector3_1_0 {
14377 pub struct WideVector3 {
14382 pub timestamp:
14388 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14389 pub meter: [f64; 3],
14395 }
14396 impl ::emcyphal_encoding::DataType for WideVector3 {
14397 const EXTENT_BYTES: Option<u32> = None;
14399 }
14400 impl ::emcyphal_encoding::Message for WideVector3 {}
14401 impl ::emcyphal_encoding::BufferType for WideVector3 {
14402 type Buffer = ::emcyphal_encoding::StaticBuffer<31>;
14403 }
14404 impl WideVector3 {}
14405 impl ::emcyphal_encoding::Serialize for WideVector3 {
14406 fn size_bits(&self) -> usize {
14407 248
14408 }
14409 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14410 cursor.write_composite(&self.timestamp);
14411 for value in (self.meter).iter() {
14412 cursor.write_f64(*value);
14413 }
14414 }
14415 }
14416 impl ::emcyphal_encoding::Deserialize for WideVector3 {
14417 fn deserialize(
14418 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14419 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14420 where
14421 Self: Sized,
14422 {
14423 Ok(WideVector3 {
14424 timestamp: { cursor.read_composite()? },
14425 meter: {
14426 [cursor.read_f64(), cursor.read_f64(), cursor.read_f64()]
14427 },
14428 })
14429 }
14430 }
14431 }
14432 }
14433 pub mod luminance {
14434 pub mod scalar_1_0 {
14435 pub struct Scalar {
14440 pub timestamp:
14446 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14447 pub candela_per_square_meter: f32,
14453 }
14454 impl ::emcyphal_encoding::DataType for Scalar {
14455 const EXTENT_BYTES: Option<u32> = None;
14457 }
14458 impl ::emcyphal_encoding::Message for Scalar {}
14459 impl ::emcyphal_encoding::BufferType for Scalar {
14460 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14461 }
14462 impl Scalar {}
14463 impl ::emcyphal_encoding::Serialize for Scalar {
14464 fn size_bits(&self) -> usize {
14465 88
14466 }
14467 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14468 cursor.write_composite(&self.timestamp);
14469 cursor.write_f32(self.candela_per_square_meter);
14470 }
14471 }
14472 impl ::emcyphal_encoding::Deserialize for Scalar {
14473 fn deserialize(
14474 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14475 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14476 where
14477 Self: Sized,
14478 {
14479 Ok(Scalar {
14480 timestamp: { cursor.read_composite()? },
14481 candela_per_square_meter: { cursor.read_f32() },
14482 })
14483 }
14484 }
14485 }
14486 }
14487 pub mod magnetic_field_strength {
14488 #[allow(deprecated)]
14489 #[cfg_attr(not(test), deprecated)]
14490 pub mod scalar_1_0 {
14491 #[cfg_attr(
14496 not(doctest),
14497 doc = " Use v1.1 instead where the unit of measure is named correctly."
14498 )]
14499 #[deprecated]
14500 pub struct Scalar {
14501 pub timestamp:
14507 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14508 pub tesla: f32,
14514 }
14515 impl ::emcyphal_encoding::DataType for Scalar {
14516 const EXTENT_BYTES: Option<u32> = None;
14518 }
14519 impl ::emcyphal_encoding::Message for Scalar {}
14520 impl ::emcyphal_encoding::BufferType for Scalar {
14521 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14522 }
14523 impl Scalar {}
14524 impl ::emcyphal_encoding::Serialize for Scalar {
14525 fn size_bits(&self) -> usize {
14526 88
14527 }
14528 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14529 cursor.write_composite(&self.timestamp);
14530 cursor.write_f32(self.tesla);
14531 }
14532 }
14533 impl ::emcyphal_encoding::Deserialize for Scalar {
14534 fn deserialize(
14535 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14536 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14537 where
14538 Self: Sized,
14539 {
14540 Ok(Scalar {
14541 timestamp: { cursor.read_composite()? },
14542 tesla: { cursor.read_f32() },
14543 })
14544 }
14545 }
14546 }
14547 pub mod scalar_1_1 {
14548 pub struct Scalar {
14553 pub timestamp:
14559 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14560 pub ampere_per_meter: f32,
14566 }
14567 impl ::emcyphal_encoding::DataType for Scalar {
14568 const EXTENT_BYTES: Option<u32> = None;
14570 }
14571 impl ::emcyphal_encoding::Message for Scalar {}
14572 impl ::emcyphal_encoding::BufferType for Scalar {
14573 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14574 }
14575 impl Scalar {}
14576 impl ::emcyphal_encoding::Serialize for Scalar {
14577 fn size_bits(&self) -> usize {
14578 88
14579 }
14580 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14581 cursor.write_composite(&self.timestamp);
14582 cursor.write_f32(self.ampere_per_meter);
14583 }
14584 }
14585 impl ::emcyphal_encoding::Deserialize for Scalar {
14586 fn deserialize(
14587 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14588 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14589 where
14590 Self: Sized,
14591 {
14592 Ok(Scalar {
14593 timestamp: { cursor.read_composite()? },
14594 ampere_per_meter: { cursor.read_f32() },
14595 })
14596 }
14597 }
14598 }
14599 #[allow(deprecated)]
14600 #[cfg_attr(not(test), deprecated)]
14601 pub mod vector3_1_0 {
14602 #[cfg_attr(
14607 not(doctest),
14608 doc = " Use v1.1 instead where the unit of measure is named correctly."
14609 )]
14610 #[deprecated]
14611 pub struct Vector3 {
14612 pub timestamp:
14618 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14619 pub tesla: [f32; 3],
14625 }
14626 impl ::emcyphal_encoding::DataType for Vector3 {
14627 const EXTENT_BYTES: Option<u32> = None;
14629 }
14630 impl ::emcyphal_encoding::Message for Vector3 {}
14631 impl ::emcyphal_encoding::BufferType for Vector3 {
14632 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
14633 }
14634 impl Vector3 {}
14635 impl ::emcyphal_encoding::Serialize for Vector3 {
14636 fn size_bits(&self) -> usize {
14637 152
14638 }
14639 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14640 cursor.write_composite(&self.timestamp);
14641 for value in (self.tesla).iter() {
14642 cursor.write_f32(*value);
14643 }
14644 }
14645 }
14646 impl ::emcyphal_encoding::Deserialize for Vector3 {
14647 fn deserialize(
14648 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14649 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14650 where
14651 Self: Sized,
14652 {
14653 Ok(Vector3 {
14654 timestamp: { cursor.read_composite()? },
14655 tesla: {
14656 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
14657 },
14658 })
14659 }
14660 }
14661 }
14662 pub mod vector3_1_1 {
14663 pub struct Vector3 {
14668 pub timestamp:
14674 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14675 pub ampere_per_meter: [f32; 3],
14681 }
14682 impl ::emcyphal_encoding::DataType for Vector3 {
14683 const EXTENT_BYTES: Option<u32> = None;
14685 }
14686 impl ::emcyphal_encoding::Message for Vector3 {}
14687 impl ::emcyphal_encoding::BufferType for Vector3 {
14688 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
14689 }
14690 impl Vector3 {}
14691 impl ::emcyphal_encoding::Serialize for Vector3 {
14692 fn size_bits(&self) -> usize {
14693 152
14694 }
14695 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14696 cursor.write_composite(&self.timestamp);
14697 for value in (self.ampere_per_meter).iter() {
14698 cursor.write_f32(*value);
14699 }
14700 }
14701 }
14702 impl ::emcyphal_encoding::Deserialize for Vector3 {
14703 fn deserialize(
14704 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14705 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14706 where
14707 Self: Sized,
14708 {
14709 Ok(Vector3 {
14710 timestamp: { cursor.read_composite()? },
14711 ampere_per_meter: {
14712 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
14713 },
14714 })
14715 }
14716 }
14717 }
14718 }
14719 pub mod magnetic_flux_density {
14720 pub mod scalar_1_0 {
14721 pub struct Scalar {
14726 pub timestamp:
14732 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14733 pub tesla: f32,
14739 }
14740 impl ::emcyphal_encoding::DataType for Scalar {
14741 const EXTENT_BYTES: Option<u32> = None;
14743 }
14744 impl ::emcyphal_encoding::Message for Scalar {}
14745 impl ::emcyphal_encoding::BufferType for Scalar {
14746 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14747 }
14748 impl Scalar {}
14749 impl ::emcyphal_encoding::Serialize for Scalar {
14750 fn size_bits(&self) -> usize {
14751 88
14752 }
14753 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14754 cursor.write_composite(&self.timestamp);
14755 cursor.write_f32(self.tesla);
14756 }
14757 }
14758 impl ::emcyphal_encoding::Deserialize for Scalar {
14759 fn deserialize(
14760 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14761 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14762 where
14763 Self: Sized,
14764 {
14765 Ok(Scalar {
14766 timestamp: { cursor.read_composite()? },
14767 tesla: { cursor.read_f32() },
14768 })
14769 }
14770 }
14771 }
14772 pub mod vector3_1_0 {
14773 pub struct Vector3 {
14778 pub timestamp:
14784 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14785 pub tesla: [f32; 3],
14791 }
14792 impl ::emcyphal_encoding::DataType for Vector3 {
14793 const EXTENT_BYTES: Option<u32> = None;
14795 }
14796 impl ::emcyphal_encoding::Message for Vector3 {}
14797 impl ::emcyphal_encoding::BufferType for Vector3 {
14798 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
14799 }
14800 impl Vector3 {}
14801 impl ::emcyphal_encoding::Serialize for Vector3 {
14802 fn size_bits(&self) -> usize {
14803 152
14804 }
14805 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14806 cursor.write_composite(&self.timestamp);
14807 for value in (self.tesla).iter() {
14808 cursor.write_f32(*value);
14809 }
14810 }
14811 }
14812 impl ::emcyphal_encoding::Deserialize for Vector3 {
14813 fn deserialize(
14814 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14815 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14816 where
14817 Self: Sized,
14818 {
14819 Ok(Vector3 {
14820 timestamp: { cursor.read_composite()? },
14821 tesla: {
14822 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
14823 },
14824 })
14825 }
14826 }
14827 }
14828 }
14829 pub mod mass {
14830 pub mod scalar_1_0 {
14831 pub struct Scalar {
14836 pub timestamp:
14842 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14843 pub kilogram: f32,
14849 }
14850 impl ::emcyphal_encoding::DataType for Scalar {
14851 const EXTENT_BYTES: Option<u32> = None;
14853 }
14854 impl ::emcyphal_encoding::Message for Scalar {}
14855 impl ::emcyphal_encoding::BufferType for Scalar {
14856 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14857 }
14858 impl Scalar {}
14859 impl ::emcyphal_encoding::Serialize for Scalar {
14860 fn size_bits(&self) -> usize {
14861 88
14862 }
14863 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14864 cursor.write_composite(&self.timestamp);
14865 cursor.write_f32(self.kilogram);
14866 }
14867 }
14868 impl ::emcyphal_encoding::Deserialize for Scalar {
14869 fn deserialize(
14870 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14871 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14872 where
14873 Self: Sized,
14874 {
14875 Ok(Scalar {
14876 timestamp: { cursor.read_composite()? },
14877 kilogram: { cursor.read_f32() },
14878 })
14879 }
14880 }
14881 }
14882 }
14883 pub mod power {
14884 pub mod scalar_1_0 {
14885 pub struct Scalar {
14890 pub timestamp:
14896 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14897 pub watt: f32,
14903 }
14904 impl ::emcyphal_encoding::DataType for Scalar {
14905 const EXTENT_BYTES: Option<u32> = None;
14907 }
14908 impl ::emcyphal_encoding::Message for Scalar {}
14909 impl ::emcyphal_encoding::BufferType for Scalar {
14910 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14911 }
14912 impl Scalar {}
14913 impl ::emcyphal_encoding::Serialize for Scalar {
14914 fn size_bits(&self) -> usize {
14915 88
14916 }
14917 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14918 cursor.write_composite(&self.timestamp);
14919 cursor.write_f32(self.watt);
14920 }
14921 }
14922 impl ::emcyphal_encoding::Deserialize for Scalar {
14923 fn deserialize(
14924 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14925 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14926 where
14927 Self: Sized,
14928 {
14929 Ok(Scalar {
14930 timestamp: { cursor.read_composite()? },
14931 watt: { cursor.read_f32() },
14932 })
14933 }
14934 }
14935 }
14936 }
14937 pub mod pressure {
14938 pub mod scalar_1_0 {
14939 pub struct Scalar {
14944 pub timestamp:
14950 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
14951 pub pascal: f32,
14957 }
14958 impl ::emcyphal_encoding::DataType for Scalar {
14959 const EXTENT_BYTES: Option<u32> = None;
14961 }
14962 impl ::emcyphal_encoding::Message for Scalar {}
14963 impl ::emcyphal_encoding::BufferType for Scalar {
14964 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
14965 }
14966 impl Scalar {}
14967 impl ::emcyphal_encoding::Serialize for Scalar {
14968 fn size_bits(&self) -> usize {
14969 88
14970 }
14971 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
14972 cursor.write_composite(&self.timestamp);
14973 cursor.write_f32(self.pascal);
14974 }
14975 }
14976 impl ::emcyphal_encoding::Deserialize for Scalar {
14977 fn deserialize(
14978 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
14979 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
14980 where
14981 Self: Sized,
14982 {
14983 Ok(Scalar {
14984 timestamp: { cursor.read_composite()? },
14985 pascal: { cursor.read_f32() },
14986 })
14987 }
14988 }
14989 }
14990 }
14991 pub mod temperature {
14992 pub mod scalar_1_0 {
14993 pub struct Scalar {
14998 pub timestamp:
15004 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15005 pub kelvin: f32,
15011 }
15012 impl ::emcyphal_encoding::DataType for Scalar {
15013 const EXTENT_BYTES: Option<u32> = None;
15015 }
15016 impl ::emcyphal_encoding::Message for Scalar {}
15017 impl ::emcyphal_encoding::BufferType for Scalar {
15018 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15019 }
15020 impl Scalar {}
15021 impl ::emcyphal_encoding::Serialize for Scalar {
15022 fn size_bits(&self) -> usize {
15023 88
15024 }
15025 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15026 cursor.write_composite(&self.timestamp);
15027 cursor.write_f32(self.kelvin);
15028 }
15029 }
15030 impl ::emcyphal_encoding::Deserialize for Scalar {
15031 fn deserialize(
15032 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15033 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15034 where
15035 Self: Sized,
15036 {
15037 Ok(Scalar {
15038 timestamp: { cursor.read_composite()? },
15039 kelvin: { cursor.read_f32() },
15040 })
15041 }
15042 }
15043 }
15044 }
15045 pub mod torque {
15046 pub mod scalar_1_0 {
15047 pub struct Scalar {
15052 pub timestamp:
15058 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15059 pub newton_meter: f32,
15065 }
15066 impl ::emcyphal_encoding::DataType for Scalar {
15067 const EXTENT_BYTES: Option<u32> = None;
15069 }
15070 impl ::emcyphal_encoding::Message for Scalar {}
15071 impl ::emcyphal_encoding::BufferType for Scalar {
15072 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15073 }
15074 impl Scalar {}
15075 impl ::emcyphal_encoding::Serialize for Scalar {
15076 fn size_bits(&self) -> usize {
15077 88
15078 }
15079 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15080 cursor.write_composite(&self.timestamp);
15081 cursor.write_f32(self.newton_meter);
15082 }
15083 }
15084 impl ::emcyphal_encoding::Deserialize for Scalar {
15085 fn deserialize(
15086 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15087 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15088 where
15089 Self: Sized,
15090 {
15091 Ok(Scalar {
15092 timestamp: { cursor.read_composite()? },
15093 newton_meter: { cursor.read_f32() },
15094 })
15095 }
15096 }
15097 }
15098 pub mod vector3_1_0 {
15099 pub struct Vector3 {
15104 pub timestamp:
15110 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15111 pub newton_meter: [f32; 3],
15117 }
15118 impl ::emcyphal_encoding::DataType for Vector3 {
15119 const EXTENT_BYTES: Option<u32> = None;
15121 }
15122 impl ::emcyphal_encoding::Message for Vector3 {}
15123 impl ::emcyphal_encoding::BufferType for Vector3 {
15124 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
15125 }
15126 impl Vector3 {}
15127 impl ::emcyphal_encoding::Serialize for Vector3 {
15128 fn size_bits(&self) -> usize {
15129 152
15130 }
15131 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15132 cursor.write_composite(&self.timestamp);
15133 for value in (self.newton_meter).iter() {
15134 cursor.write_f32(*value);
15135 }
15136 }
15137 }
15138 impl ::emcyphal_encoding::Deserialize for Vector3 {
15139 fn deserialize(
15140 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15141 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15142 where
15143 Self: Sized,
15144 {
15145 Ok(Vector3 {
15146 timestamp: { cursor.read_composite()? },
15147 newton_meter: {
15148 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
15149 },
15150 })
15151 }
15152 }
15153 }
15154 }
15155 pub mod velocity {
15156 pub mod scalar_1_0 {
15157 pub struct Scalar {
15162 pub timestamp:
15168 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15169 pub meter_per_second: f32,
15175 }
15176 impl ::emcyphal_encoding::DataType for Scalar {
15177 const EXTENT_BYTES: Option<u32> = None;
15179 }
15180 impl ::emcyphal_encoding::Message for Scalar {}
15181 impl ::emcyphal_encoding::BufferType for Scalar {
15182 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15183 }
15184 impl Scalar {}
15185 impl ::emcyphal_encoding::Serialize for Scalar {
15186 fn size_bits(&self) -> usize {
15187 88
15188 }
15189 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15190 cursor.write_composite(&self.timestamp);
15191 cursor.write_f32(self.meter_per_second);
15192 }
15193 }
15194 impl ::emcyphal_encoding::Deserialize for Scalar {
15195 fn deserialize(
15196 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15197 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15198 where
15199 Self: Sized,
15200 {
15201 Ok(Scalar {
15202 timestamp: { cursor.read_composite()? },
15203 meter_per_second: { cursor.read_f32() },
15204 })
15205 }
15206 }
15207 }
15208 pub mod vector3_1_0 {
15209 pub struct Vector3 {
15214 pub timestamp:
15220 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15221 pub meter_per_second: [f32; 3],
15227 }
15228 impl ::emcyphal_encoding::DataType for Vector3 {
15229 const EXTENT_BYTES: Option<u32> = None;
15231 }
15232 impl ::emcyphal_encoding::Message for Vector3 {}
15233 impl ::emcyphal_encoding::BufferType for Vector3 {
15234 type Buffer = ::emcyphal_encoding::StaticBuffer<19>;
15235 }
15236 impl Vector3 {}
15237 impl ::emcyphal_encoding::Serialize for Vector3 {
15238 fn size_bits(&self) -> usize {
15239 152
15240 }
15241 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15242 cursor.write_composite(&self.timestamp);
15243 for value in (self.meter_per_second).iter() {
15244 cursor.write_f32(*value);
15245 }
15246 }
15247 }
15248 impl ::emcyphal_encoding::Deserialize for Vector3 {
15249 fn deserialize(
15250 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15251 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15252 where
15253 Self: Sized,
15254 {
15255 Ok(Vector3 {
15256 timestamp: { cursor.read_composite()? },
15257 meter_per_second: {
15258 [cursor.read_f32(), cursor.read_f32(), cursor.read_f32()]
15259 },
15260 })
15261 }
15262 }
15263 }
15264 }
15265 pub mod voltage {
15266 pub mod scalar_1_0 {
15267 pub struct Scalar {
15272 pub timestamp:
15278 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15279 pub volt: f32,
15285 }
15286 impl ::emcyphal_encoding::DataType for Scalar {
15287 const EXTENT_BYTES: Option<u32> = None;
15289 }
15290 impl ::emcyphal_encoding::Message for Scalar {}
15291 impl ::emcyphal_encoding::BufferType for Scalar {
15292 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15293 }
15294 impl Scalar {}
15295 impl ::emcyphal_encoding::Serialize for Scalar {
15296 fn size_bits(&self) -> usize {
15297 88
15298 }
15299 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15300 cursor.write_composite(&self.timestamp);
15301 cursor.write_f32(self.volt);
15302 }
15303 }
15304 impl ::emcyphal_encoding::Deserialize for Scalar {
15305 fn deserialize(
15306 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15307 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15308 where
15309 Self: Sized,
15310 {
15311 Ok(Scalar {
15312 timestamp: { cursor.read_composite()? },
15313 volt: { cursor.read_f32() },
15314 })
15315 }
15316 }
15317 }
15318 }
15319 pub mod volume {
15320 pub mod scalar_1_0 {
15321 pub struct Scalar {
15326 pub timestamp:
15332 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15333 pub cubic_meter: f32,
15339 }
15340 impl ::emcyphal_encoding::DataType for Scalar {
15341 const EXTENT_BYTES: Option<u32> = None;
15343 }
15344 impl ::emcyphal_encoding::Message for Scalar {}
15345 impl ::emcyphal_encoding::BufferType for Scalar {
15346 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15347 }
15348 impl Scalar {}
15349 impl ::emcyphal_encoding::Serialize for Scalar {
15350 fn size_bits(&self) -> usize {
15351 88
15352 }
15353 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15354 cursor.write_composite(&self.timestamp);
15355 cursor.write_f32(self.cubic_meter);
15356 }
15357 }
15358 impl ::emcyphal_encoding::Deserialize for Scalar {
15359 fn deserialize(
15360 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15361 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15362 where
15363 Self: Sized,
15364 {
15365 Ok(Scalar {
15366 timestamp: { cursor.read_composite()? },
15367 cubic_meter: { cursor.read_f32() },
15368 })
15369 }
15370 }
15371 }
15372 }
15373 pub mod volumetric_flow_rate {
15374 pub mod scalar_1_0 {
15375 pub struct Scalar {
15380 pub timestamp:
15386 crate::uavcan::time::synchronized_timestamp_1_0::SynchronizedTimestamp,
15387 pub cubic_meter_per_second: f32,
15393 }
15394 impl ::emcyphal_encoding::DataType for Scalar {
15395 const EXTENT_BYTES: Option<u32> = None;
15397 }
15398 impl ::emcyphal_encoding::Message for Scalar {}
15399 impl ::emcyphal_encoding::BufferType for Scalar {
15400 type Buffer = ::emcyphal_encoding::StaticBuffer<11>;
15401 }
15402 impl Scalar {}
15403 impl ::emcyphal_encoding::Serialize for Scalar {
15404 fn size_bits(&self) -> usize {
15405 88
15406 }
15407 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15408 cursor.write_composite(&self.timestamp);
15409 cursor.write_f32(self.cubic_meter_per_second);
15410 }
15411 }
15412 impl ::emcyphal_encoding::Deserialize for Scalar {
15413 fn deserialize(
15414 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15415 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15416 where
15417 Self: Sized,
15418 {
15419 Ok(Scalar {
15420 timestamp: { cursor.read_composite()? },
15421 cubic_meter_per_second: { cursor.read_f32() },
15422 })
15423 }
15424 }
15425 }
15426 }
15427 }
15428 pub mod unit {
15429 pub mod acceleration {
15430 pub mod scalar_1_0 {
15431 #[derive(
15436 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15437 )]
15438 #[repr(C, packed)]
15439 pub struct Scalar {
15440 pub meter_per_second_per_second: f32,
15446 }
15447 impl ::emcyphal_encoding::DataType for Scalar {
15448 const EXTENT_BYTES: Option<u32> = None;
15450 }
15451 impl ::emcyphal_encoding::Message for Scalar {}
15452 impl ::emcyphal_encoding::BufferType for Scalar {
15453 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
15454 }
15455 impl Scalar {}
15456 impl ::emcyphal_encoding::Serialize for Scalar {
15457 fn size_bits(&self) -> usize {
15458 32
15459 }
15460 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15461 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15462 }
15463 }
15464 impl ::emcyphal_encoding::Deserialize for Scalar {
15465 fn deserialize(
15466 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15467 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15468 where
15469 Self: Sized,
15470 {
15471 Ok(Self::deserialize_zero_copy(cursor))
15472 }
15473 }
15474 #[test]
15475 fn test_layout() {
15476 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
15477 assert_eq!(
15478 ::core::mem::offset_of!(Scalar, meter_per_second_per_second) * 8,
15479 0
15480 );
15481 }
15482 }
15483 pub mod vector3_1_0 {
15484 #[derive(
15489 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15490 )]
15491 #[repr(C, packed)]
15492 pub struct Vector3 {
15493 pub meter_per_second_per_second: [f32; 3],
15499 }
15500 impl ::emcyphal_encoding::DataType for Vector3 {
15501 const EXTENT_BYTES: Option<u32> = None;
15503 }
15504 impl ::emcyphal_encoding::Message for Vector3 {}
15505 impl ::emcyphal_encoding::BufferType for Vector3 {
15506 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
15507 }
15508 impl Vector3 {}
15509 impl ::emcyphal_encoding::Serialize for Vector3 {
15510 fn size_bits(&self) -> usize {
15511 96
15512 }
15513 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15514 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15515 }
15516 }
15517 impl ::emcyphal_encoding::Deserialize for Vector3 {
15518 fn deserialize(
15519 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15520 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15521 where
15522 Self: Sized,
15523 {
15524 Ok(Self::deserialize_zero_copy(cursor))
15525 }
15526 }
15527 #[test]
15528 fn test_layout() {
15529 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
15530 assert_eq!(
15531 ::core::mem::offset_of!(Vector3, meter_per_second_per_second) * 8,
15532 0
15533 );
15534 }
15535 }
15536 }
15537 pub mod angle {
15538 pub mod narrow_scalar_1_0 {
15539 #[derive(
15544 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15545 )]
15546 #[repr(C, packed)]
15547 pub struct NarrowScalar {
15548 pub radian: ::half::f16,
15554 }
15555 impl ::emcyphal_encoding::DataType for NarrowScalar {
15556 const EXTENT_BYTES: Option<u32> = None;
15558 }
15559 impl ::emcyphal_encoding::Message for NarrowScalar {}
15560 impl ::emcyphal_encoding::BufferType for NarrowScalar {
15561 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
15562 }
15563 impl NarrowScalar {}
15564 impl ::emcyphal_encoding::Serialize for NarrowScalar {
15565 fn size_bits(&self) -> usize {
15566 16
15567 }
15568 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15569 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15570 }
15571 }
15572 impl ::emcyphal_encoding::Deserialize for NarrowScalar {
15573 fn deserialize(
15574 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15575 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15576 where
15577 Self: Sized,
15578 {
15579 Ok(Self::deserialize_zero_copy(cursor))
15580 }
15581 }
15582 #[test]
15583 fn test_layout() {
15584 assert_eq!(::core::mem::size_of::<NarrowScalar>() * 8, 16);
15585 assert_eq!(::core::mem::offset_of!(NarrowScalar, radian) * 8, 0);
15586 }
15587 }
15588 pub mod narrow_vector3_1_0 {
15589 #[derive(
15594 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15595 )]
15596 #[repr(C, packed)]
15597 pub struct NarrowVector3 {
15598 pub radian: [::half::f16; 3],
15604 }
15605 impl ::emcyphal_encoding::DataType for NarrowVector3 {
15606 const EXTENT_BYTES: Option<u32> = None;
15608 }
15609 impl ::emcyphal_encoding::Message for NarrowVector3 {}
15610 impl ::emcyphal_encoding::BufferType for NarrowVector3 {
15611 type Buffer = ::emcyphal_encoding::StaticBuffer<6>;
15612 }
15613 impl NarrowVector3 {}
15614 impl ::emcyphal_encoding::Serialize for NarrowVector3 {
15615 fn size_bits(&self) -> usize {
15616 48
15617 }
15618 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15619 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15620 }
15621 }
15622 impl ::emcyphal_encoding::Deserialize for NarrowVector3 {
15623 fn deserialize(
15624 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15625 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15626 where
15627 Self: Sized,
15628 {
15629 Ok(Self::deserialize_zero_copy(cursor))
15630 }
15631 }
15632 #[test]
15633 fn test_layout() {
15634 assert_eq!(::core::mem::size_of::<NarrowVector3>() * 8, 48);
15635 assert_eq!(::core::mem::offset_of!(NarrowVector3, radian) * 8, 0);
15636 }
15637 }
15638 pub mod quaternion_1_0 {
15639 #[derive(
15644 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15645 )]
15646 #[repr(C, packed)]
15647 pub struct Quaternion {
15648 pub wxyz: [f32; 4],
15654 }
15655 impl ::emcyphal_encoding::DataType for Quaternion {
15656 const EXTENT_BYTES: Option<u32> = None;
15658 }
15659 impl ::emcyphal_encoding::Message for Quaternion {}
15660 impl ::emcyphal_encoding::BufferType for Quaternion {
15661 type Buffer = ::emcyphal_encoding::StaticBuffer<16>;
15662 }
15663 impl Quaternion {}
15664 impl ::emcyphal_encoding::Serialize for Quaternion {
15665 fn size_bits(&self) -> usize {
15666 128
15667 }
15668 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15669 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15670 }
15671 }
15672 impl ::emcyphal_encoding::Deserialize for Quaternion {
15673 fn deserialize(
15674 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15675 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15676 where
15677 Self: Sized,
15678 {
15679 Ok(Self::deserialize_zero_copy(cursor))
15680 }
15681 }
15682 #[test]
15683 fn test_layout() {
15684 assert_eq!(::core::mem::size_of::<Quaternion>() * 8, 128);
15685 assert_eq!(::core::mem::offset_of!(Quaternion, wxyz) * 8, 0);
15686 }
15687 }
15688 pub mod scalar_1_0 {
15689 #[derive(
15694 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15695 )]
15696 #[repr(C, packed)]
15697 pub struct Scalar {
15698 pub radian: f32,
15704 }
15705 impl ::emcyphal_encoding::DataType for Scalar {
15706 const EXTENT_BYTES: Option<u32> = None;
15708 }
15709 impl ::emcyphal_encoding::Message for Scalar {}
15710 impl ::emcyphal_encoding::BufferType for Scalar {
15711 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
15712 }
15713 impl Scalar {}
15714 impl ::emcyphal_encoding::Serialize for Scalar {
15715 fn size_bits(&self) -> usize {
15716 32
15717 }
15718 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15719 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15720 }
15721 }
15722 impl ::emcyphal_encoding::Deserialize for Scalar {
15723 fn deserialize(
15724 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15725 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15726 where
15727 Self: Sized,
15728 {
15729 Ok(Self::deserialize_zero_copy(cursor))
15730 }
15731 }
15732 #[test]
15733 fn test_layout() {
15734 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
15735 assert_eq!(::core::mem::offset_of!(Scalar, radian) * 8, 0);
15736 }
15737 }
15738 pub mod vector3_1_0 {
15739 #[derive(
15744 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15745 )]
15746 #[repr(C, packed)]
15747 pub struct Vector3 {
15748 pub radian: [f32; 3],
15754 }
15755 impl ::emcyphal_encoding::DataType for Vector3 {
15756 const EXTENT_BYTES: Option<u32> = None;
15758 }
15759 impl ::emcyphal_encoding::Message for Vector3 {}
15760 impl ::emcyphal_encoding::BufferType for Vector3 {
15761 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
15762 }
15763 impl Vector3 {}
15764 impl ::emcyphal_encoding::Serialize for Vector3 {
15765 fn size_bits(&self) -> usize {
15766 96
15767 }
15768 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15769 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15770 }
15771 }
15772 impl ::emcyphal_encoding::Deserialize for Vector3 {
15773 fn deserialize(
15774 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15775 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15776 where
15777 Self: Sized,
15778 {
15779 Ok(Self::deserialize_zero_copy(cursor))
15780 }
15781 }
15782 #[test]
15783 fn test_layout() {
15784 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
15785 assert_eq!(::core::mem::offset_of!(Vector3, radian) * 8, 0);
15786 }
15787 }
15788 pub mod wide_scalar_1_0 {
15789 #[derive(
15794 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15795 )]
15796 #[repr(C, packed)]
15797 pub struct WideScalar {
15798 pub radian: f64,
15804 }
15805 impl ::emcyphal_encoding::DataType for WideScalar {
15806 const EXTENT_BYTES: Option<u32> = None;
15808 }
15809 impl ::emcyphal_encoding::Message for WideScalar {}
15810 impl ::emcyphal_encoding::BufferType for WideScalar {
15811 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
15812 }
15813 impl WideScalar {}
15814 impl ::emcyphal_encoding::Serialize for WideScalar {
15815 fn size_bits(&self) -> usize {
15816 64
15817 }
15818 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15819 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15820 }
15821 }
15822 impl ::emcyphal_encoding::Deserialize for WideScalar {
15823 fn deserialize(
15824 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15825 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15826 where
15827 Self: Sized,
15828 {
15829 Ok(Self::deserialize_zero_copy(cursor))
15830 }
15831 }
15832 #[test]
15833 fn test_layout() {
15834 assert_eq!(::core::mem::size_of::<WideScalar>() * 8, 64);
15835 assert_eq!(::core::mem::offset_of!(WideScalar, radian) * 8, 0);
15836 }
15837 }
15838 pub mod wide_vector3_1_0 {
15839 #[derive(
15844 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15845 )]
15846 #[repr(C, packed)]
15847 pub struct WideVector3 {
15848 pub radian: [f64; 3],
15854 }
15855 impl ::emcyphal_encoding::DataType for WideVector3 {
15856 const EXTENT_BYTES: Option<u32> = None;
15858 }
15859 impl ::emcyphal_encoding::Message for WideVector3 {}
15860 impl ::emcyphal_encoding::BufferType for WideVector3 {
15861 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
15862 }
15863 impl WideVector3 {}
15864 impl ::emcyphal_encoding::Serialize for WideVector3 {
15865 fn size_bits(&self) -> usize {
15866 192
15867 }
15868 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15869 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15870 }
15871 }
15872 impl ::emcyphal_encoding::Deserialize for WideVector3 {
15873 fn deserialize(
15874 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15875 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15876 where
15877 Self: Sized,
15878 {
15879 Ok(Self::deserialize_zero_copy(cursor))
15880 }
15881 }
15882 #[test]
15883 fn test_layout() {
15884 assert_eq!(::core::mem::size_of::<WideVector3>() * 8, 192);
15885 assert_eq!(::core::mem::offset_of!(WideVector3, radian) * 8, 0);
15886 }
15887 }
15888 }
15889 pub mod angular_acceleration {
15890 pub mod scalar_1_0 {
15891 #[derive(
15896 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15897 )]
15898 #[repr(C, packed)]
15899 pub struct Scalar {
15900 pub radian_per_second_per_second: f32,
15906 }
15907 impl ::emcyphal_encoding::DataType for Scalar {
15908 const EXTENT_BYTES: Option<u32> = None;
15910 }
15911 impl ::emcyphal_encoding::Message for Scalar {}
15912 impl ::emcyphal_encoding::BufferType for Scalar {
15913 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
15914 }
15915 impl Scalar {}
15916 impl ::emcyphal_encoding::Serialize for Scalar {
15917 fn size_bits(&self) -> usize {
15918 32
15919 }
15920 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15921 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15922 }
15923 }
15924 impl ::emcyphal_encoding::Deserialize for Scalar {
15925 fn deserialize(
15926 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15927 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15928 where
15929 Self: Sized,
15930 {
15931 Ok(Self::deserialize_zero_copy(cursor))
15932 }
15933 }
15934 #[test]
15935 fn test_layout() {
15936 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
15937 assert_eq!(
15938 ::core::mem::offset_of!(Scalar, radian_per_second_per_second) * 8,
15939 0
15940 );
15941 }
15942 }
15943 pub mod vector3_1_0 {
15944 #[derive(
15949 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
15950 )]
15951 #[repr(C, packed)]
15952 pub struct Vector3 {
15953 pub radian_per_second_per_second: [f32; 3],
15959 }
15960 impl ::emcyphal_encoding::DataType for Vector3 {
15961 const EXTENT_BYTES: Option<u32> = None;
15963 }
15964 impl ::emcyphal_encoding::Message for Vector3 {}
15965 impl ::emcyphal_encoding::BufferType for Vector3 {
15966 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
15967 }
15968 impl Vector3 {}
15969 impl ::emcyphal_encoding::Serialize for Vector3 {
15970 fn size_bits(&self) -> usize {
15971 96
15972 }
15973 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
15974 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
15975 }
15976 }
15977 impl ::emcyphal_encoding::Deserialize for Vector3 {
15978 fn deserialize(
15979 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
15980 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
15981 where
15982 Self: Sized,
15983 {
15984 Ok(Self::deserialize_zero_copy(cursor))
15985 }
15986 }
15987 #[test]
15988 fn test_layout() {
15989 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
15990 assert_eq!(
15991 ::core::mem::offset_of!(Vector3, radian_per_second_per_second) * 8,
15992 0
15993 );
15994 }
15995 }
15996 }
15997 pub mod angular_velocity {
15998 pub mod scalar_1_0 {
15999 #[derive(
16004 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16005 )]
16006 #[repr(C, packed)]
16007 pub struct Scalar {
16008 pub radian_per_second: f32,
16014 }
16015 impl ::emcyphal_encoding::DataType for Scalar {
16016 const EXTENT_BYTES: Option<u32> = None;
16018 }
16019 impl ::emcyphal_encoding::Message for Scalar {}
16020 impl ::emcyphal_encoding::BufferType for Scalar {
16021 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16022 }
16023 impl Scalar {}
16024 impl ::emcyphal_encoding::Serialize for Scalar {
16025 fn size_bits(&self) -> usize {
16026 32
16027 }
16028 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16029 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16030 }
16031 }
16032 impl ::emcyphal_encoding::Deserialize for Scalar {
16033 fn deserialize(
16034 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16035 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16036 where
16037 Self: Sized,
16038 {
16039 Ok(Self::deserialize_zero_copy(cursor))
16040 }
16041 }
16042 #[test]
16043 fn test_layout() {
16044 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16045 assert_eq!(::core::mem::offset_of!(Scalar, radian_per_second) * 8, 0);
16046 }
16047 }
16048 pub mod vector3_1_0 {
16049 #[derive(
16054 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16055 )]
16056 #[repr(C, packed)]
16057 pub struct Vector3 {
16058 pub radian_per_second: [f32; 3],
16064 }
16065 impl ::emcyphal_encoding::DataType for Vector3 {
16066 const EXTENT_BYTES: Option<u32> = None;
16068 }
16069 impl ::emcyphal_encoding::Message for Vector3 {}
16070 impl ::emcyphal_encoding::BufferType for Vector3 {
16071 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
16072 }
16073 impl Vector3 {}
16074 impl ::emcyphal_encoding::Serialize for Vector3 {
16075 fn size_bits(&self) -> usize {
16076 96
16077 }
16078 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16079 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16080 }
16081 }
16082 impl ::emcyphal_encoding::Deserialize for Vector3 {
16083 fn deserialize(
16084 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16085 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16086 where
16087 Self: Sized,
16088 {
16089 Ok(Self::deserialize_zero_copy(cursor))
16090 }
16091 }
16092 #[test]
16093 fn test_layout() {
16094 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
16095 assert_eq!(::core::mem::offset_of!(Vector3, radian_per_second) * 8, 0);
16096 }
16097 }
16098 }
16099 pub mod duration {
16100 pub mod scalar_1_0 {
16101 #[derive(
16106 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16107 )]
16108 #[repr(C, packed)]
16109 pub struct Scalar {
16110 pub second: f32,
16116 }
16117 impl ::emcyphal_encoding::DataType for Scalar {
16118 const EXTENT_BYTES: Option<u32> = None;
16120 }
16121 impl ::emcyphal_encoding::Message for Scalar {}
16122 impl ::emcyphal_encoding::BufferType for Scalar {
16123 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16124 }
16125 impl Scalar {}
16126 impl ::emcyphal_encoding::Serialize for Scalar {
16127 fn size_bits(&self) -> usize {
16128 32
16129 }
16130 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16131 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16132 }
16133 }
16134 impl ::emcyphal_encoding::Deserialize for Scalar {
16135 fn deserialize(
16136 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16137 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16138 where
16139 Self: Sized,
16140 {
16141 Ok(Self::deserialize_zero_copy(cursor))
16142 }
16143 }
16144 #[test]
16145 fn test_layout() {
16146 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16147 assert_eq!(::core::mem::offset_of!(Scalar, second) * 8, 0);
16148 }
16149 }
16150 pub mod wide_scalar_1_0 {
16151 #[derive(
16156 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16157 )]
16158 #[repr(C, packed)]
16159 pub struct WideScalar {
16160 pub second: f64,
16166 }
16167 impl ::emcyphal_encoding::DataType for WideScalar {
16168 const EXTENT_BYTES: Option<u32> = None;
16170 }
16171 impl ::emcyphal_encoding::Message for WideScalar {}
16172 impl ::emcyphal_encoding::BufferType for WideScalar {
16173 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
16174 }
16175 impl WideScalar {}
16176 impl ::emcyphal_encoding::Serialize for WideScalar {
16177 fn size_bits(&self) -> usize {
16178 64
16179 }
16180 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16181 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16182 }
16183 }
16184 impl ::emcyphal_encoding::Deserialize for WideScalar {
16185 fn deserialize(
16186 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16187 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16188 where
16189 Self: Sized,
16190 {
16191 Ok(Self::deserialize_zero_copy(cursor))
16192 }
16193 }
16194 #[test]
16195 fn test_layout() {
16196 assert_eq!(::core::mem::size_of::<WideScalar>() * 8, 64);
16197 assert_eq!(::core::mem::offset_of!(WideScalar, second) * 8, 0);
16198 }
16199 }
16200 }
16201 pub mod electric_charge {
16202 pub mod scalar_1_0 {
16203 #[derive(
16208 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16209 )]
16210 #[repr(C, packed)]
16211 pub struct Scalar {
16212 pub coulomb: f32,
16218 }
16219 impl ::emcyphal_encoding::DataType for Scalar {
16220 const EXTENT_BYTES: Option<u32> = None;
16222 }
16223 impl ::emcyphal_encoding::Message for Scalar {}
16224 impl ::emcyphal_encoding::BufferType for Scalar {
16225 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16226 }
16227 impl Scalar {}
16228 impl ::emcyphal_encoding::Serialize for Scalar {
16229 fn size_bits(&self) -> usize {
16230 32
16231 }
16232 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16233 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16234 }
16235 }
16236 impl ::emcyphal_encoding::Deserialize for Scalar {
16237 fn deserialize(
16238 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16239 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16240 where
16241 Self: Sized,
16242 {
16243 Ok(Self::deserialize_zero_copy(cursor))
16244 }
16245 }
16246 #[test]
16247 fn test_layout() {
16248 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16249 assert_eq!(::core::mem::offset_of!(Scalar, coulomb) * 8, 0);
16250 }
16251 }
16252 }
16253 pub mod electric_current {
16254 pub mod scalar_1_0 {
16255 #[derive(
16260 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16261 )]
16262 #[repr(C, packed)]
16263 pub struct Scalar {
16264 pub ampere: f32,
16270 }
16271 impl ::emcyphal_encoding::DataType for Scalar {
16272 const EXTENT_BYTES: Option<u32> = None;
16274 }
16275 impl ::emcyphal_encoding::Message for Scalar {}
16276 impl ::emcyphal_encoding::BufferType for Scalar {
16277 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16278 }
16279 impl Scalar {}
16280 impl ::emcyphal_encoding::Serialize for Scalar {
16281 fn size_bits(&self) -> usize {
16282 32
16283 }
16284 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16285 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16286 }
16287 }
16288 impl ::emcyphal_encoding::Deserialize for Scalar {
16289 fn deserialize(
16290 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16291 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16292 where
16293 Self: Sized,
16294 {
16295 Ok(Self::deserialize_zero_copy(cursor))
16296 }
16297 }
16298 #[test]
16299 fn test_layout() {
16300 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16301 assert_eq!(::core::mem::offset_of!(Scalar, ampere) * 8, 0);
16302 }
16303 }
16304 }
16305 pub mod energy {
16306 pub mod scalar_1_0 {
16307 #[derive(
16312 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16313 )]
16314 #[repr(C, packed)]
16315 pub struct Scalar {
16316 pub joule: f32,
16322 }
16323 impl ::emcyphal_encoding::DataType for Scalar {
16324 const EXTENT_BYTES: Option<u32> = None;
16326 }
16327 impl ::emcyphal_encoding::Message for Scalar {}
16328 impl ::emcyphal_encoding::BufferType for Scalar {
16329 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16330 }
16331 impl Scalar {}
16332 impl ::emcyphal_encoding::Serialize for Scalar {
16333 fn size_bits(&self) -> usize {
16334 32
16335 }
16336 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16337 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16338 }
16339 }
16340 impl ::emcyphal_encoding::Deserialize for Scalar {
16341 fn deserialize(
16342 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16343 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16344 where
16345 Self: Sized,
16346 {
16347 Ok(Self::deserialize_zero_copy(cursor))
16348 }
16349 }
16350 #[test]
16351 fn test_layout() {
16352 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16353 assert_eq!(::core::mem::offset_of!(Scalar, joule) * 8, 0);
16354 }
16355 }
16356 }
16357 pub mod force {
16358 pub mod scalar_1_0 {
16359 #[derive(
16364 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16365 )]
16366 #[repr(C, packed)]
16367 pub struct Scalar {
16368 pub newton: f32,
16374 }
16375 impl ::emcyphal_encoding::DataType for Scalar {
16376 const EXTENT_BYTES: Option<u32> = None;
16378 }
16379 impl ::emcyphal_encoding::Message for Scalar {}
16380 impl ::emcyphal_encoding::BufferType for Scalar {
16381 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16382 }
16383 impl Scalar {}
16384 impl ::emcyphal_encoding::Serialize for Scalar {
16385 fn size_bits(&self) -> usize {
16386 32
16387 }
16388 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16389 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16390 }
16391 }
16392 impl ::emcyphal_encoding::Deserialize for Scalar {
16393 fn deserialize(
16394 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16395 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16396 where
16397 Self: Sized,
16398 {
16399 Ok(Self::deserialize_zero_copy(cursor))
16400 }
16401 }
16402 #[test]
16403 fn test_layout() {
16404 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16405 assert_eq!(::core::mem::offset_of!(Scalar, newton) * 8, 0);
16406 }
16407 }
16408 pub mod vector3_1_0 {
16409 #[derive(
16414 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16415 )]
16416 #[repr(C, packed)]
16417 pub struct Vector3 {
16418 pub newton: [f32; 3],
16424 }
16425 impl ::emcyphal_encoding::DataType for Vector3 {
16426 const EXTENT_BYTES: Option<u32> = None;
16428 }
16429 impl ::emcyphal_encoding::Message for Vector3 {}
16430 impl ::emcyphal_encoding::BufferType for Vector3 {
16431 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
16432 }
16433 impl Vector3 {}
16434 impl ::emcyphal_encoding::Serialize for Vector3 {
16435 fn size_bits(&self) -> usize {
16436 96
16437 }
16438 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16439 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16440 }
16441 }
16442 impl ::emcyphal_encoding::Deserialize for Vector3 {
16443 fn deserialize(
16444 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16445 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16446 where
16447 Self: Sized,
16448 {
16449 Ok(Self::deserialize_zero_copy(cursor))
16450 }
16451 }
16452 #[test]
16453 fn test_layout() {
16454 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
16455 assert_eq!(::core::mem::offset_of!(Vector3, newton) * 8, 0);
16456 }
16457 }
16458 }
16459 pub mod frequency {
16460 pub mod scalar_1_0 {
16461 #[derive(
16466 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16467 )]
16468 #[repr(C, packed)]
16469 pub struct Scalar {
16470 pub hertz: f32,
16476 }
16477 impl ::emcyphal_encoding::DataType for Scalar {
16478 const EXTENT_BYTES: Option<u32> = None;
16480 }
16481 impl ::emcyphal_encoding::Message for Scalar {}
16482 impl ::emcyphal_encoding::BufferType for Scalar {
16483 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16484 }
16485 impl Scalar {}
16486 impl ::emcyphal_encoding::Serialize for Scalar {
16487 fn size_bits(&self) -> usize {
16488 32
16489 }
16490 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16491 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16492 }
16493 }
16494 impl ::emcyphal_encoding::Deserialize for Scalar {
16495 fn deserialize(
16496 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16497 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16498 where
16499 Self: Sized,
16500 {
16501 Ok(Self::deserialize_zero_copy(cursor))
16502 }
16503 }
16504 #[test]
16505 fn test_layout() {
16506 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16507 assert_eq!(::core::mem::offset_of!(Scalar, hertz) * 8, 0);
16508 }
16509 }
16510 }
16511 pub mod length {
16512 pub mod narrow_scalar_1_0 {
16513 #[derive(
16518 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16519 )]
16520 #[repr(C, packed)]
16521 pub struct NarrowScalar {
16522 pub meter: ::half::f16,
16528 }
16529 impl ::emcyphal_encoding::DataType for NarrowScalar {
16530 const EXTENT_BYTES: Option<u32> = None;
16532 }
16533 impl ::emcyphal_encoding::Message for NarrowScalar {}
16534 impl ::emcyphal_encoding::BufferType for NarrowScalar {
16535 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
16536 }
16537 impl NarrowScalar {}
16538 impl ::emcyphal_encoding::Serialize for NarrowScalar {
16539 fn size_bits(&self) -> usize {
16540 16
16541 }
16542 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16543 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16544 }
16545 }
16546 impl ::emcyphal_encoding::Deserialize for NarrowScalar {
16547 fn deserialize(
16548 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16549 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16550 where
16551 Self: Sized,
16552 {
16553 Ok(Self::deserialize_zero_copy(cursor))
16554 }
16555 }
16556 #[test]
16557 fn test_layout() {
16558 assert_eq!(::core::mem::size_of::<NarrowScalar>() * 8, 16);
16559 assert_eq!(::core::mem::offset_of!(NarrowScalar, meter) * 8, 0);
16560 }
16561 }
16562 pub mod narrow_vector3_1_0 {
16563 #[derive(
16568 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16569 )]
16570 #[repr(C, packed)]
16571 pub struct NarrowVector3 {
16572 pub meter: [::half::f16; 3],
16578 }
16579 impl ::emcyphal_encoding::DataType for NarrowVector3 {
16580 const EXTENT_BYTES: Option<u32> = None;
16582 }
16583 impl ::emcyphal_encoding::Message for NarrowVector3 {}
16584 impl ::emcyphal_encoding::BufferType for NarrowVector3 {
16585 type Buffer = ::emcyphal_encoding::StaticBuffer<6>;
16586 }
16587 impl NarrowVector3 {}
16588 impl ::emcyphal_encoding::Serialize for NarrowVector3 {
16589 fn size_bits(&self) -> usize {
16590 48
16591 }
16592 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16593 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16594 }
16595 }
16596 impl ::emcyphal_encoding::Deserialize for NarrowVector3 {
16597 fn deserialize(
16598 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16599 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16600 where
16601 Self: Sized,
16602 {
16603 Ok(Self::deserialize_zero_copy(cursor))
16604 }
16605 }
16606 #[test]
16607 fn test_layout() {
16608 assert_eq!(::core::mem::size_of::<NarrowVector3>() * 8, 48);
16609 assert_eq!(::core::mem::offset_of!(NarrowVector3, meter) * 8, 0);
16610 }
16611 }
16612 pub mod scalar_1_0 {
16613 #[derive(
16618 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16619 )]
16620 #[repr(C, packed)]
16621 pub struct Scalar {
16622 pub meter: f32,
16628 }
16629 impl ::emcyphal_encoding::DataType for Scalar {
16630 const EXTENT_BYTES: Option<u32> = None;
16632 }
16633 impl ::emcyphal_encoding::Message for Scalar {}
16634 impl ::emcyphal_encoding::BufferType for Scalar {
16635 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16636 }
16637 impl Scalar {}
16638 impl ::emcyphal_encoding::Serialize for Scalar {
16639 fn size_bits(&self) -> usize {
16640 32
16641 }
16642 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16643 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16644 }
16645 }
16646 impl ::emcyphal_encoding::Deserialize for Scalar {
16647 fn deserialize(
16648 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16649 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16650 where
16651 Self: Sized,
16652 {
16653 Ok(Self::deserialize_zero_copy(cursor))
16654 }
16655 }
16656 #[test]
16657 fn test_layout() {
16658 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16659 assert_eq!(::core::mem::offset_of!(Scalar, meter) * 8, 0);
16660 }
16661 }
16662 pub mod vector3_1_0 {
16663 #[derive(
16668 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16669 )]
16670 #[repr(C, packed)]
16671 pub struct Vector3 {
16672 pub meter: [f32; 3],
16678 }
16679 impl ::emcyphal_encoding::DataType for Vector3 {
16680 const EXTENT_BYTES: Option<u32> = None;
16682 }
16683 impl ::emcyphal_encoding::Message for Vector3 {}
16684 impl ::emcyphal_encoding::BufferType for Vector3 {
16685 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
16686 }
16687 impl Vector3 {}
16688 impl ::emcyphal_encoding::Serialize for Vector3 {
16689 fn size_bits(&self) -> usize {
16690 96
16691 }
16692 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16693 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16694 }
16695 }
16696 impl ::emcyphal_encoding::Deserialize for Vector3 {
16697 fn deserialize(
16698 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16699 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16700 where
16701 Self: Sized,
16702 {
16703 Ok(Self::deserialize_zero_copy(cursor))
16704 }
16705 }
16706 #[test]
16707 fn test_layout() {
16708 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
16709 assert_eq!(::core::mem::offset_of!(Vector3, meter) * 8, 0);
16710 }
16711 }
16712 pub mod wide_scalar_1_0 {
16713 #[derive(
16718 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16719 )]
16720 #[repr(C, packed)]
16721 pub struct WideScalar {
16722 pub meter: f64,
16728 }
16729 impl ::emcyphal_encoding::DataType for WideScalar {
16730 const EXTENT_BYTES: Option<u32> = None;
16732 }
16733 impl ::emcyphal_encoding::Message for WideScalar {}
16734 impl ::emcyphal_encoding::BufferType for WideScalar {
16735 type Buffer = ::emcyphal_encoding::StaticBuffer<8>;
16736 }
16737 impl WideScalar {}
16738 impl ::emcyphal_encoding::Serialize for WideScalar {
16739 fn size_bits(&self) -> usize {
16740 64
16741 }
16742 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16743 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16744 }
16745 }
16746 impl ::emcyphal_encoding::Deserialize for WideScalar {
16747 fn deserialize(
16748 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16749 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16750 where
16751 Self: Sized,
16752 {
16753 Ok(Self::deserialize_zero_copy(cursor))
16754 }
16755 }
16756 #[test]
16757 fn test_layout() {
16758 assert_eq!(::core::mem::size_of::<WideScalar>() * 8, 64);
16759 assert_eq!(::core::mem::offset_of!(WideScalar, meter) * 8, 0);
16760 }
16761 }
16762 pub mod wide_vector3_1_0 {
16763 #[derive(
16768 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16769 )]
16770 #[repr(C, packed)]
16771 pub struct WideVector3 {
16772 pub meter: [f64; 3],
16778 }
16779 impl ::emcyphal_encoding::DataType for WideVector3 {
16780 const EXTENT_BYTES: Option<u32> = None;
16782 }
16783 impl ::emcyphal_encoding::Message for WideVector3 {}
16784 impl ::emcyphal_encoding::BufferType for WideVector3 {
16785 type Buffer = ::emcyphal_encoding::StaticBuffer<24>;
16786 }
16787 impl WideVector3 {}
16788 impl ::emcyphal_encoding::Serialize for WideVector3 {
16789 fn size_bits(&self) -> usize {
16790 192
16791 }
16792 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16793 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16794 }
16795 }
16796 impl ::emcyphal_encoding::Deserialize for WideVector3 {
16797 fn deserialize(
16798 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16799 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16800 where
16801 Self: Sized,
16802 {
16803 Ok(Self::deserialize_zero_copy(cursor))
16804 }
16805 }
16806 #[test]
16807 fn test_layout() {
16808 assert_eq!(::core::mem::size_of::<WideVector3>() * 8, 192);
16809 assert_eq!(::core::mem::offset_of!(WideVector3, meter) * 8, 0);
16810 }
16811 }
16812 }
16813 pub mod luminance {
16814 pub mod scalar_1_0 {
16815 #[derive(
16820 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16821 )]
16822 #[repr(C, packed)]
16823 pub struct Scalar {
16824 pub candela_per_square_meter: f32,
16830 }
16831 impl ::emcyphal_encoding::DataType for Scalar {
16832 const EXTENT_BYTES: Option<u32> = None;
16834 }
16835 impl ::emcyphal_encoding::Message for Scalar {}
16836 impl ::emcyphal_encoding::BufferType for Scalar {
16837 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16838 }
16839 impl Scalar {}
16840 impl ::emcyphal_encoding::Serialize for Scalar {
16841 fn size_bits(&self) -> usize {
16842 32
16843 }
16844 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16845 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16846 }
16847 }
16848 impl ::emcyphal_encoding::Deserialize for Scalar {
16849 fn deserialize(
16850 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16851 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16852 where
16853 Self: Sized,
16854 {
16855 Ok(Self::deserialize_zero_copy(cursor))
16856 }
16857 }
16858 #[test]
16859 fn test_layout() {
16860 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16861 assert_eq!(
16862 ::core::mem::offset_of!(Scalar, candela_per_square_meter) * 8,
16863 0
16864 );
16865 }
16866 }
16867 }
16868 pub mod magnetic_field_strength {
16869 #[allow(deprecated)]
16870 #[cfg_attr(not(test), deprecated)]
16871 pub mod scalar_1_0 {
16872 #[cfg_attr(
16877 not(doctest),
16878 doc = " Use v1.1 instead where the unit of measure is named correctly."
16879 )]
16880 #[derive(
16881 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16882 )]
16883 #[repr(C, packed)]
16884 #[deprecated]
16885 pub struct Scalar {
16886 pub tesla: f32,
16892 }
16893 impl ::emcyphal_encoding::DataType for Scalar {
16894 const EXTENT_BYTES: Option<u32> = None;
16896 }
16897 impl ::emcyphal_encoding::Message for Scalar {}
16898 impl ::emcyphal_encoding::BufferType for Scalar {
16899 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16900 }
16901 impl Scalar {}
16902 impl ::emcyphal_encoding::Serialize for Scalar {
16903 fn size_bits(&self) -> usize {
16904 32
16905 }
16906 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16907 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16908 }
16909 }
16910 impl ::emcyphal_encoding::Deserialize for Scalar {
16911 fn deserialize(
16912 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16913 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16914 where
16915 Self: Sized,
16916 {
16917 Ok(Self::deserialize_zero_copy(cursor))
16918 }
16919 }
16920 #[test]
16921 fn test_layout() {
16922 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16923 assert_eq!(::core::mem::offset_of!(Scalar, tesla) * 8, 0);
16924 }
16925 }
16926 pub mod scalar_1_1 {
16927 #[derive(
16932 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16933 )]
16934 #[repr(C, packed)]
16935 pub struct Scalar {
16936 pub ampere_per_meter: f32,
16942 }
16943 impl ::emcyphal_encoding::DataType for Scalar {
16944 const EXTENT_BYTES: Option<u32> = None;
16946 }
16947 impl ::emcyphal_encoding::Message for Scalar {}
16948 impl ::emcyphal_encoding::BufferType for Scalar {
16949 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
16950 }
16951 impl Scalar {}
16952 impl ::emcyphal_encoding::Serialize for Scalar {
16953 fn size_bits(&self) -> usize {
16954 32
16955 }
16956 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
16957 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
16958 }
16959 }
16960 impl ::emcyphal_encoding::Deserialize for Scalar {
16961 fn deserialize(
16962 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
16963 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
16964 where
16965 Self: Sized,
16966 {
16967 Ok(Self::deserialize_zero_copy(cursor))
16968 }
16969 }
16970 #[test]
16971 fn test_layout() {
16972 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
16973 assert_eq!(::core::mem::offset_of!(Scalar, ampere_per_meter) * 8, 0);
16974 }
16975 }
16976 #[allow(deprecated)]
16977 #[cfg_attr(not(test), deprecated)]
16978 pub mod vector3_1_0 {
16979 #[cfg_attr(
16984 not(doctest),
16985 doc = " Use v1.1 instead where the unit of measure is named correctly."
16986 )]
16987 #[derive(
16988 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
16989 )]
16990 #[repr(C, packed)]
16991 #[deprecated]
16992 pub struct Vector3 {
16993 pub tesla: [f32; 3],
16999 }
17000 impl ::emcyphal_encoding::DataType for Vector3 {
17001 const EXTENT_BYTES: Option<u32> = None;
17003 }
17004 impl ::emcyphal_encoding::Message for Vector3 {}
17005 impl ::emcyphal_encoding::BufferType for Vector3 {
17006 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
17007 }
17008 impl Vector3 {}
17009 impl ::emcyphal_encoding::Serialize for Vector3 {
17010 fn size_bits(&self) -> usize {
17011 96
17012 }
17013 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17014 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17015 }
17016 }
17017 impl ::emcyphal_encoding::Deserialize for Vector3 {
17018 fn deserialize(
17019 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17020 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17021 where
17022 Self: Sized,
17023 {
17024 Ok(Self::deserialize_zero_copy(cursor))
17025 }
17026 }
17027 #[test]
17028 fn test_layout() {
17029 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
17030 assert_eq!(::core::mem::offset_of!(Vector3, tesla) * 8, 0);
17031 }
17032 }
17033 pub mod vector3_1_1 {
17034 #[derive(
17039 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17040 )]
17041 #[repr(C, packed)]
17042 pub struct Vector3 {
17043 pub ampere_per_meter: [f32; 3],
17049 }
17050 impl ::emcyphal_encoding::DataType for Vector3 {
17051 const EXTENT_BYTES: Option<u32> = None;
17053 }
17054 impl ::emcyphal_encoding::Message for Vector3 {}
17055 impl ::emcyphal_encoding::BufferType for Vector3 {
17056 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
17057 }
17058 impl Vector3 {}
17059 impl ::emcyphal_encoding::Serialize for Vector3 {
17060 fn size_bits(&self) -> usize {
17061 96
17062 }
17063 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17064 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17065 }
17066 }
17067 impl ::emcyphal_encoding::Deserialize for Vector3 {
17068 fn deserialize(
17069 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17070 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17071 where
17072 Self: Sized,
17073 {
17074 Ok(Self::deserialize_zero_copy(cursor))
17075 }
17076 }
17077 #[test]
17078 fn test_layout() {
17079 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
17080 assert_eq!(::core::mem::offset_of!(Vector3, ampere_per_meter) * 8, 0);
17081 }
17082 }
17083 }
17084 pub mod magnetic_flux_density {
17085 pub mod scalar_1_0 {
17086 #[derive(
17091 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17092 )]
17093 #[repr(C, packed)]
17094 pub struct Scalar {
17095 pub tesla: f32,
17101 }
17102 impl ::emcyphal_encoding::DataType for Scalar {
17103 const EXTENT_BYTES: Option<u32> = None;
17105 }
17106 impl ::emcyphal_encoding::Message for Scalar {}
17107 impl ::emcyphal_encoding::BufferType for Scalar {
17108 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17109 }
17110 impl Scalar {}
17111 impl ::emcyphal_encoding::Serialize for Scalar {
17112 fn size_bits(&self) -> usize {
17113 32
17114 }
17115 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17116 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17117 }
17118 }
17119 impl ::emcyphal_encoding::Deserialize for Scalar {
17120 fn deserialize(
17121 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17122 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17123 where
17124 Self: Sized,
17125 {
17126 Ok(Self::deserialize_zero_copy(cursor))
17127 }
17128 }
17129 #[test]
17130 fn test_layout() {
17131 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17132 assert_eq!(::core::mem::offset_of!(Scalar, tesla) * 8, 0);
17133 }
17134 }
17135 pub mod vector3_1_0 {
17136 #[derive(
17141 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17142 )]
17143 #[repr(C, packed)]
17144 pub struct Vector3 {
17145 pub tesla: [f32; 3],
17151 }
17152 impl ::emcyphal_encoding::DataType for Vector3 {
17153 const EXTENT_BYTES: Option<u32> = None;
17155 }
17156 impl ::emcyphal_encoding::Message for Vector3 {}
17157 impl ::emcyphal_encoding::BufferType for Vector3 {
17158 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
17159 }
17160 impl Vector3 {}
17161 impl ::emcyphal_encoding::Serialize for Vector3 {
17162 fn size_bits(&self) -> usize {
17163 96
17164 }
17165 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17166 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17167 }
17168 }
17169 impl ::emcyphal_encoding::Deserialize for Vector3 {
17170 fn deserialize(
17171 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17172 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17173 where
17174 Self: Sized,
17175 {
17176 Ok(Self::deserialize_zero_copy(cursor))
17177 }
17178 }
17179 #[test]
17180 fn test_layout() {
17181 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
17182 assert_eq!(::core::mem::offset_of!(Vector3, tesla) * 8, 0);
17183 }
17184 }
17185 }
17186 pub mod mass {
17187 pub mod scalar_1_0 {
17188 #[derive(
17193 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17194 )]
17195 #[repr(C, packed)]
17196 pub struct Scalar {
17197 pub kilogram: f32,
17203 }
17204 impl ::emcyphal_encoding::DataType for Scalar {
17205 const EXTENT_BYTES: Option<u32> = None;
17207 }
17208 impl ::emcyphal_encoding::Message for Scalar {}
17209 impl ::emcyphal_encoding::BufferType for Scalar {
17210 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17211 }
17212 impl Scalar {}
17213 impl ::emcyphal_encoding::Serialize for Scalar {
17214 fn size_bits(&self) -> usize {
17215 32
17216 }
17217 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17218 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17219 }
17220 }
17221 impl ::emcyphal_encoding::Deserialize for Scalar {
17222 fn deserialize(
17223 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17224 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17225 where
17226 Self: Sized,
17227 {
17228 Ok(Self::deserialize_zero_copy(cursor))
17229 }
17230 }
17231 #[test]
17232 fn test_layout() {
17233 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17234 assert_eq!(::core::mem::offset_of!(Scalar, kilogram) * 8, 0);
17235 }
17236 }
17237 }
17238 pub mod power {
17239 pub mod scalar_1_0 {
17240 #[derive(
17245 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17246 )]
17247 #[repr(C, packed)]
17248 pub struct Scalar {
17249 pub watt: f32,
17255 }
17256 impl ::emcyphal_encoding::DataType for Scalar {
17257 const EXTENT_BYTES: Option<u32> = None;
17259 }
17260 impl ::emcyphal_encoding::Message for Scalar {}
17261 impl ::emcyphal_encoding::BufferType for Scalar {
17262 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17263 }
17264 impl Scalar {}
17265 impl ::emcyphal_encoding::Serialize for Scalar {
17266 fn size_bits(&self) -> usize {
17267 32
17268 }
17269 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17270 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17271 }
17272 }
17273 impl ::emcyphal_encoding::Deserialize for Scalar {
17274 fn deserialize(
17275 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17276 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17277 where
17278 Self: Sized,
17279 {
17280 Ok(Self::deserialize_zero_copy(cursor))
17281 }
17282 }
17283 #[test]
17284 fn test_layout() {
17285 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17286 assert_eq!(::core::mem::offset_of!(Scalar, watt) * 8, 0);
17287 }
17288 }
17289 }
17290 pub mod pressure {
17291 pub mod scalar_1_0 {
17292 #[derive(
17297 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17298 )]
17299 #[repr(C, packed)]
17300 pub struct Scalar {
17301 pub pascal: f32,
17307 }
17308 impl ::emcyphal_encoding::DataType for Scalar {
17309 const EXTENT_BYTES: Option<u32> = None;
17311 }
17312 impl ::emcyphal_encoding::Message for Scalar {}
17313 impl ::emcyphal_encoding::BufferType for Scalar {
17314 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17315 }
17316 impl Scalar {}
17317 impl ::emcyphal_encoding::Serialize for Scalar {
17318 fn size_bits(&self) -> usize {
17319 32
17320 }
17321 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17322 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17323 }
17324 }
17325 impl ::emcyphal_encoding::Deserialize for Scalar {
17326 fn deserialize(
17327 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17328 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17329 where
17330 Self: Sized,
17331 {
17332 Ok(Self::deserialize_zero_copy(cursor))
17333 }
17334 }
17335 #[test]
17336 fn test_layout() {
17337 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17338 assert_eq!(::core::mem::offset_of!(Scalar, pascal) * 8, 0);
17339 }
17340 }
17341 }
17342 pub mod temperature {
17343 pub mod scalar_1_0 {
17344 #[derive(
17349 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17350 )]
17351 #[repr(C, packed)]
17352 pub struct Scalar {
17353 pub kelvin: f32,
17359 }
17360 impl ::emcyphal_encoding::DataType for Scalar {
17361 const EXTENT_BYTES: Option<u32> = None;
17363 }
17364 impl ::emcyphal_encoding::Message for Scalar {}
17365 impl ::emcyphal_encoding::BufferType for Scalar {
17366 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17367 }
17368 impl Scalar {}
17369 impl ::emcyphal_encoding::Serialize for Scalar {
17370 fn size_bits(&self) -> usize {
17371 32
17372 }
17373 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17374 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17375 }
17376 }
17377 impl ::emcyphal_encoding::Deserialize for Scalar {
17378 fn deserialize(
17379 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17380 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17381 where
17382 Self: Sized,
17383 {
17384 Ok(Self::deserialize_zero_copy(cursor))
17385 }
17386 }
17387 #[test]
17388 fn test_layout() {
17389 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17390 assert_eq!(::core::mem::offset_of!(Scalar, kelvin) * 8, 0);
17391 }
17392 }
17393 }
17394 pub mod torque {
17395 pub mod scalar_1_0 {
17396 #[derive(
17401 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17402 )]
17403 #[repr(C, packed)]
17404 pub struct Scalar {
17405 pub newton_meter: f32,
17411 }
17412 impl ::emcyphal_encoding::DataType for Scalar {
17413 const EXTENT_BYTES: Option<u32> = None;
17415 }
17416 impl ::emcyphal_encoding::Message for Scalar {}
17417 impl ::emcyphal_encoding::BufferType for Scalar {
17418 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17419 }
17420 impl Scalar {}
17421 impl ::emcyphal_encoding::Serialize for Scalar {
17422 fn size_bits(&self) -> usize {
17423 32
17424 }
17425 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17426 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17427 }
17428 }
17429 impl ::emcyphal_encoding::Deserialize for Scalar {
17430 fn deserialize(
17431 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17432 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17433 where
17434 Self: Sized,
17435 {
17436 Ok(Self::deserialize_zero_copy(cursor))
17437 }
17438 }
17439 #[test]
17440 fn test_layout() {
17441 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17442 assert_eq!(::core::mem::offset_of!(Scalar, newton_meter) * 8, 0);
17443 }
17444 }
17445 pub mod vector3_1_0 {
17446 #[derive(
17451 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17452 )]
17453 #[repr(C, packed)]
17454 pub struct Vector3 {
17455 pub newton_meter: [f32; 3],
17461 }
17462 impl ::emcyphal_encoding::DataType for Vector3 {
17463 const EXTENT_BYTES: Option<u32> = None;
17465 }
17466 impl ::emcyphal_encoding::Message for Vector3 {}
17467 impl ::emcyphal_encoding::BufferType for Vector3 {
17468 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
17469 }
17470 impl Vector3 {}
17471 impl ::emcyphal_encoding::Serialize for Vector3 {
17472 fn size_bits(&self) -> usize {
17473 96
17474 }
17475 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17476 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17477 }
17478 }
17479 impl ::emcyphal_encoding::Deserialize for Vector3 {
17480 fn deserialize(
17481 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17482 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17483 where
17484 Self: Sized,
17485 {
17486 Ok(Self::deserialize_zero_copy(cursor))
17487 }
17488 }
17489 #[test]
17490 fn test_layout() {
17491 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
17492 assert_eq!(::core::mem::offset_of!(Vector3, newton_meter) * 8, 0);
17493 }
17494 }
17495 }
17496 pub mod velocity {
17497 pub mod scalar_1_0 {
17498 #[derive(
17503 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17504 )]
17505 #[repr(C, packed)]
17506 pub struct Scalar {
17507 pub meter_per_second: f32,
17513 }
17514 impl ::emcyphal_encoding::DataType for Scalar {
17515 const EXTENT_BYTES: Option<u32> = None;
17517 }
17518 impl ::emcyphal_encoding::Message for Scalar {}
17519 impl ::emcyphal_encoding::BufferType for Scalar {
17520 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17521 }
17522 impl Scalar {}
17523 impl ::emcyphal_encoding::Serialize for Scalar {
17524 fn size_bits(&self) -> usize {
17525 32
17526 }
17527 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17528 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17529 }
17530 }
17531 impl ::emcyphal_encoding::Deserialize for Scalar {
17532 fn deserialize(
17533 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17534 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17535 where
17536 Self: Sized,
17537 {
17538 Ok(Self::deserialize_zero_copy(cursor))
17539 }
17540 }
17541 #[test]
17542 fn test_layout() {
17543 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17544 assert_eq!(::core::mem::offset_of!(Scalar, meter_per_second) * 8, 0);
17545 }
17546 }
17547 pub mod vector3_1_0 {
17548 #[derive(
17553 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17554 )]
17555 #[repr(C, packed)]
17556 pub struct Vector3 {
17557 pub meter_per_second: [f32; 3],
17563 }
17564 impl ::emcyphal_encoding::DataType for Vector3 {
17565 const EXTENT_BYTES: Option<u32> = None;
17567 }
17568 impl ::emcyphal_encoding::Message for Vector3 {}
17569 impl ::emcyphal_encoding::BufferType for Vector3 {
17570 type Buffer = ::emcyphal_encoding::StaticBuffer<12>;
17571 }
17572 impl Vector3 {}
17573 impl ::emcyphal_encoding::Serialize for Vector3 {
17574 fn size_bits(&self) -> usize {
17575 96
17576 }
17577 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17578 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17579 }
17580 }
17581 impl ::emcyphal_encoding::Deserialize for Vector3 {
17582 fn deserialize(
17583 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17584 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17585 where
17586 Self: Sized,
17587 {
17588 Ok(Self::deserialize_zero_copy(cursor))
17589 }
17590 }
17591 #[test]
17592 fn test_layout() {
17593 assert_eq!(::core::mem::size_of::<Vector3>() * 8, 96);
17594 assert_eq!(::core::mem::offset_of!(Vector3, meter_per_second) * 8, 0);
17595 }
17596 }
17597 }
17598 pub mod voltage {
17599 pub mod scalar_1_0 {
17600 #[derive(
17605 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17606 )]
17607 #[repr(C, packed)]
17608 pub struct Scalar {
17609 pub volt: f32,
17615 }
17616 impl ::emcyphal_encoding::DataType for Scalar {
17617 const EXTENT_BYTES: Option<u32> = None;
17619 }
17620 impl ::emcyphal_encoding::Message for Scalar {}
17621 impl ::emcyphal_encoding::BufferType for Scalar {
17622 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17623 }
17624 impl Scalar {}
17625 impl ::emcyphal_encoding::Serialize for Scalar {
17626 fn size_bits(&self) -> usize {
17627 32
17628 }
17629 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17630 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17631 }
17632 }
17633 impl ::emcyphal_encoding::Deserialize for Scalar {
17634 fn deserialize(
17635 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17636 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17637 where
17638 Self: Sized,
17639 {
17640 Ok(Self::deserialize_zero_copy(cursor))
17641 }
17642 }
17643 #[test]
17644 fn test_layout() {
17645 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17646 assert_eq!(::core::mem::offset_of!(Scalar, volt) * 8, 0);
17647 }
17648 }
17649 }
17650 pub mod volume {
17651 pub mod scalar_1_0 {
17652 #[derive(
17657 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17658 )]
17659 #[repr(C, packed)]
17660 pub struct Scalar {
17661 pub cubic_meter: f32,
17667 }
17668 impl ::emcyphal_encoding::DataType for Scalar {
17669 const EXTENT_BYTES: Option<u32> = None;
17671 }
17672 impl ::emcyphal_encoding::Message for Scalar {}
17673 impl ::emcyphal_encoding::BufferType for Scalar {
17674 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17675 }
17676 impl Scalar {}
17677 impl ::emcyphal_encoding::Serialize for Scalar {
17678 fn size_bits(&self) -> usize {
17679 32
17680 }
17681 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17682 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17683 }
17684 }
17685 impl ::emcyphal_encoding::Deserialize for Scalar {
17686 fn deserialize(
17687 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17688 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17689 where
17690 Self: Sized,
17691 {
17692 Ok(Self::deserialize_zero_copy(cursor))
17693 }
17694 }
17695 #[test]
17696 fn test_layout() {
17697 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17698 assert_eq!(::core::mem::offset_of!(Scalar, cubic_meter) * 8, 0);
17699 }
17700 }
17701 }
17702 pub mod volumetric_flow_rate {
17703 pub mod scalar_1_0 {
17704 #[derive(
17709 ::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable,
17710 )]
17711 #[repr(C, packed)]
17712 pub struct Scalar {
17713 pub cubic_meter_per_second: f32,
17719 }
17720 impl ::emcyphal_encoding::DataType for Scalar {
17721 const EXTENT_BYTES: Option<u32> = None;
17723 }
17724 impl ::emcyphal_encoding::Message for Scalar {}
17725 impl ::emcyphal_encoding::BufferType for Scalar {
17726 type Buffer = ::emcyphal_encoding::StaticBuffer<4>;
17727 }
17728 impl Scalar {}
17729 impl ::emcyphal_encoding::Serialize for Scalar {
17730 fn size_bits(&self) -> usize {
17731 32
17732 }
17733 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17734 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17735 }
17736 }
17737 impl ::emcyphal_encoding::Deserialize for Scalar {
17738 fn deserialize(
17739 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17740 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17741 where
17742 Self: Sized,
17743 {
17744 Ok(Self::deserialize_zero_copy(cursor))
17745 }
17746 }
17747 #[test]
17748 fn test_layout() {
17749 assert_eq!(::core::mem::size_of::<Scalar>() * 8, 32);
17750 assert_eq!(
17751 ::core::mem::offset_of!(Scalar, cubic_meter_per_second) * 8,
17752 0
17753 );
17754 }
17755 }
17756 }
17757 }
17758 }
17759 pub mod time {
17760 pub mod get_synchronization_master_info_0_1 {
17761 #[cfg_attr(not(doctest), doc = "The fixed ID of this service")]
17762 pub const SERVICE: ::emcyphal_core::ServiceId =
17763 ::emcyphal_core::ServiceId::from_u16_truncating(510);
17764
17765 #[cfg_attr(
17770 not(doctest),
17771 doc = " Every node that acts as a time synchronization master, or is capable of acting as such,\n should support this service.\n Its objective is to provide information about which time system is currently used in the network.\n\n Once a time system is chosen, it cannot be changed as long as at least one node on the network is running.\n In other words, the time system cannot be changed while the network is operating.\n An implication of this is that if there are redundant time synchronization masters, they all shall\n use the same time system always."
17772 )]
17773 #[derive(::zerocopy::IntoBytes, ::zerocopy::FromBytes, ::zerocopy::Immutable)]
17774 #[repr(C, packed)]
17775 pub struct GetSynchronizationMasterInfoRequest {}
17776 impl ::emcyphal_encoding::DataType for GetSynchronizationMasterInfoRequest {
17777 const EXTENT_BYTES: Option<u32> = Some(48);
17779 }
17780 impl ::emcyphal_encoding::Request for GetSynchronizationMasterInfoRequest {}
17781 impl ::emcyphal_encoding::BufferType for GetSynchronizationMasterInfoRequest {
17782 type Buffer = ::emcyphal_encoding::StaticBuffer<0>;
17783 }
17784 impl GetSynchronizationMasterInfoRequest {}
17785 impl ::emcyphal_encoding::Serialize for GetSynchronizationMasterInfoRequest {
17786 fn size_bits(&self) -> usize {
17787 0
17788 }
17789 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17790 cursor.write_aligned_bytes(::zerocopy::IntoBytes::as_bytes(self));
17791 }
17792 }
17793 impl ::emcyphal_encoding::Deserialize for GetSynchronizationMasterInfoRequest {
17794 fn deserialize(
17795 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17796 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17797 where
17798 Self: Sized,
17799 {
17800 Ok(Self::deserialize_zero_copy(cursor))
17801 }
17802 }
17803 #[test]
17804 fn test_layout() {
17805 assert_eq!(
17806 ::core::mem::size_of::<GetSynchronizationMasterInfoRequest>() * 8,
17807 0
17808 );
17809 }
17810
17811 pub struct GetSynchronizationMasterInfoResponse {
17816 #[cfg_attr(
17817 not(doctest),
17818 doc = " [second^2]\n Error variance, in second^2, of the time value reported by this master.\n This value is allowed to change freely while the master is running.\n For example, if the master's own clock is synchronized with a GNSS, the error variance is expected to increase\n as signal reception deteriorates. If the signal is lost, this value is expected to grow steadily, the rate of\n growth would be dependent on the quality of the time keeping hardware available locally (bad hardware yields\n faster growth). Once the signal is regained, this value would drop back to nominal."
17819 )]
17820 pub error_variance: f32,
17826 #[cfg_attr(
17827 not(doctest),
17828 doc = " Time system currently in use by the master.\n Cannot be changed while the network is operating."
17829 )]
17830 pub time_system: crate::uavcan::time::time_system_0_1::TimeSystem,
17836 #[cfg_attr(
17837 not(doctest),
17838 doc = " Actual information about TAI provided by this master, if supported.\n The fields in this data type are optional."
17839 )]
17840 pub tai_info: crate::uavcan::time::tai_info_0_1::TAIInfo,
17846 }
17847 impl ::emcyphal_encoding::DataType for GetSynchronizationMasterInfoResponse {
17848 const EXTENT_BYTES: Option<u32> = Some(192);
17850 }
17851 impl ::emcyphal_encoding::Response for GetSynchronizationMasterInfoResponse {}
17852 impl ::emcyphal_encoding::BufferType for GetSynchronizationMasterInfoResponse {
17853 type Buffer = ::emcyphal_encoding::StaticBuffer<7>;
17854 }
17855 impl GetSynchronizationMasterInfoResponse {}
17856 impl ::emcyphal_encoding::Serialize for GetSynchronizationMasterInfoResponse {
17857 fn size_bits(&self) -> usize {
17858 56
17859 }
17860 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17861 cursor.write_f32(self.error_variance);
17862 cursor.write_composite(&self.time_system);
17863 cursor.write_composite(&self.tai_info);
17864 }
17865 }
17866 impl ::emcyphal_encoding::Deserialize for GetSynchronizationMasterInfoResponse {
17867 fn deserialize(
17868 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17869 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17870 where
17871 Self: Sized,
17872 {
17873 Ok(GetSynchronizationMasterInfoResponse {
17874 error_variance: { cursor.read_f32() },
17875 time_system: { cursor.read_composite()? },
17876 tai_info: { cursor.read_composite()? },
17877 })
17878 }
17879 }
17880 }
17881 pub mod synchronization_1_0 {
17882 #[cfg_attr(not(doctest), doc = "The fixed subject ID for this message type")]
17883 pub const SUBJECT: ::emcyphal_core::SubjectId =
17884 ::emcyphal_core::SubjectId::from_u16_truncating(7168);
17885
17886 #[cfg_attr(
17891 not(doctest),
17892 doc = " Network-wide time synchronization message.\n Any node that publishes timestamped data should use this time reference.\n\n The time synchronization algorithm is based on the work\n \"Implementing a Distributed High-Resolution Real-Time Clock using the CAN-Bus\" by M. Gergeleit and H. Streich.\n The general idea of the algorithm is to have one or more nodes that periodically publish a message of this type\n containing the exact timestamp of the PREVIOUS transmission of this message.\n A node that publishes this message periodically is referred to as a \"time synchronization master\",\n whereas nodes that synchronize their clocks with the master are referred to as \"time synchronization slaves\".\n\n Once a time base is chosen, it cannot be changed as long as at least one node on the network is running.\n In other words, the time base cannot be changed while the network is operating.\n An implication of this is that if there are redundant time synchronization masters, they all shall\n use the same time base.\n\n The resolution is dependent on the transport and its physical layer, but generally it can be assumed\n to be close to one bit time but not better than one microsecond (e.g., for a 500 kbps CAN bus,\n the resolution is two microseconds). The maximum accuracy is achievable only if the transport layer\n supports precise timestamping in hardware; otherwise, the accuracy may be degraded.\n\n This algorithm allows the slaves to precisely estimate the difference (i.e., phase error) between their\n local time and the master clock they are synchronized with. The algorithm for clock rate adjustment\n is entirely implementation-defined (for example, a simple phase-locked loop or a PID rate controller can be used).\n\n The network can accommodate more than one time synchronization master for purposes of increased reliability:\n if one master fails, the others will continue to provide the network with accurate and consistent time information.\n The risk of undesirable transients while the masters are swapped is mitigated by the requirement that all masters\n use the same time base at all times, as described above.\n\n The master with the lowest node-ID is called the \"dominant master\". The current dominant master ceases to be one\n if its last synchronization message was published more than 3X seconds ago, where X is the time interval\n between the last and the previous messages published by it. In this case, the master with the next-higher node-ID\n will take over as the new dominant master. The current dominant master will be displaced immediately as soon as\n the first message from a new master with a lower node-ID is seen on the bus.\n\n In the presence of multiple masters, they all publish their time synchronization messages concurrently at all times.\n The slaves shall listen to the master with the lowest node-ID and ignore the messages published by masters with\n higher node-ID values.\n\n Currently, there is a work underway to develop and validate a highly robust fault-operational time synchronization\n algorithm where the slaves select the median time base among all available masters rather than using only the\n one with the lowest node-ID value. Follow the work at https://forum.opencyphal.org. When complete, this algorithm\n will be added in a backward-compatible way as an option for high-reliability systems.\n\n For networks with redundant transports, the timestamp value published on different interfaces is likely to be\n different, since different transports are generally not expected to be synchronized. Synchronization slaves\n are allowed to use any of the available redundant interfaces for synchronization at their discretion.\n\n The following pseudocode shows the logic of a time synchronization master. This example assumes that the master\n does not need to synchronize its own clock with other masters on the bus, which is the case if the current master\n is the only master, or if all masters synchronize their clocks with a robust external source, e.g., a GNSS system.\n If several masters need to synchronize their clock through the bus, their logic will be extended with the\n slave-side behavior explained later.\n\n // State variables\n transfer_id := 0;\n previous_tx_timestamp_per_iface[NUM_IFACES] := {0};\n\n // This function publishes a message with a specified transfer-ID using only one transport interface.\n function publishMessage(transfer_id, iface_index, msg);\n\n // This callback is invoked when the transport layer completes the transmission of a time sync message.\n // Observe that the time sync message is always a single-frame message by virtue of its small size.\n // The tx_timestamp argument contains the exact timestamp when the transport frame was delivered to the bus.\n function messageTxTimestampCallback(iface_index, tx_timestamp)\n {\n previous_tx_timestamp_per_iface[iface_index] := tx_timestamp;\n }\n\n // Publishes messages of type uavcan.time.Synchronization to each available transport interface.\n // It is assumed that this function is invoked with a fixed frequency not lower than 1 hertz.\n function publishTimeSync()\n {\n for (i := 0; i < NUM_IFACES; i++)\n {\n message := uavcan.time.Synchronization();\n message.previous_transmission_timestamp_usec := previous_tx_timestamp_per_iface[i];\n previous_tx_timestamp_per_iface[i] := 0;\n publishMessage(transfer_id, i, message);\n }\n transfer_id++; // Overflow shall be handled correctly\n }\n\n (end of the master-side logic pseudocode)\n The following pseudocode describes the logic of a time synchronization slave.\n\n // State variables:\n previous_rx_real_timestamp := 0; // This clock is being synchronized\n previous_rx_monotonic_timestamp := 0; // Monotonic time -- doesn't leap or change rate\n previous_transfer_id := 0;\n state := STATE_UPDATE; // Variants: STATE_UPDATE, STATE_ADJUST\n master_node_id := -1; // Invalid value\n iface_index := -1; // Invalid value\n\n // This function adjusts the local clock by the specified amount\n function adjustLocalTime(phase_error);\n\n function adjust(message)\n {\n // Clock adjustment will be performed every second message\n local_time_phase_error := previous_rx_real_timestamp - msg.previous_transmission_timestamp_microsecond;\n adjustLocalTime(local_time_phase_error);\n state := STATE_UPDATE;\n }\n\n function update(message)\n {\n // A message is assumed to have two timestamps:\n // Real - sampled from the clock that is being synchronized\n // Monotonic - clock that never leaps and never changes rate\n previous_rx_real_timestamp := message.rx_real_timestamp;\n previous_rx_monotonic_timestamp := message.rx_monotonic_timestamp;\n master_node_id := message.source_node_id;\n iface_index := message.iface_index;\n previous_transfer_id := message.transfer_id;\n state := STATE_ADJUST;\n }\n\n // Accepts the message of type uavcan.time.Synchronization\n function handleReceivedTimeSyncMessage(message)\n {\n time_since_previous_msg := message.monotonic_timestamp - previous_rx_monotonic_timestamp;\n\n needs_init := (master_node_id < 0) or (iface_index < 0);\n switch_master := message.source_node_id < master_node_id;\n\n // The value publisher_timeout is computed as described in the specification (3x interval)\n publisher_timed_out := time_since_previous_msg > publisher_timeout;\n\n if (needs_init or switch_master or publisher_timed_out)\n {\n update(message);\n }\n else if ((message.iface_index == iface_index) and (message.source_node_id == master_node_id))\n {\n // Revert the state to STATE_UPDATE if needed\n if (state == STATE_ADJUST)\n {\n msg_invalid := message.previous_transmission_timestamp_microsecond == 0;\n // Overflow shall be handled correctly\n wrong_tid := message.transfer_id != (previous_transfer_id + 1);\n wrong_timing := time_since_previous_msg > MAX_PUBLICATION_PERIOD;\n if (msg_invalid or wrong_tid or wrong_timing)\n {\n state := STATE_UPDATE;\n }\n }\n // Handle the current state\n if (state == STATE_ADJUST)\n {\n adjust(message);\n }\n else\n {\n update(message);\n }\n } // else ignore\n }\n\n (end of the slave-side logic pseudocode)"
17893 )]
17894 pub struct Synchronization {
17895 #[cfg_attr(
17896 not(doctest),
17897 doc = " The time when the PREVIOUS message was transmitted from the current publisher, in microseconds.\n If this message is published for the first time, or if the previous transmission was more than\n one second ago, this field shall be zero."
17898 )]
17899 pub previous_transmission_timestamp_microsecond: u64,
17905 }
17906 impl ::emcyphal_encoding::DataType for Synchronization {
17907 const EXTENT_BYTES: Option<u32> = None;
17909 }
17910 impl ::emcyphal_encoding::Message for Synchronization {}
17911 impl ::emcyphal_encoding::BufferType for Synchronization {
17912 type Buffer = ::emcyphal_encoding::StaticBuffer<7>;
17913 }
17914 impl Synchronization {
17915 #[cfg_attr(
17916 not(doctest),
17917 doc = " [second]\n Publication period limits.\n A master should not change its publication period while running."
17918 )]
17919 pub const MAX_PUBLICATION_PERIOD: u8 = 1;
17920 #[cfg_attr(
17921 not(doctest),
17922 doc = " Synchronization slaves should normally switch to a new master if the current master was silent\n for thrice the interval between the reception of the last two messages published by it.\n For example, imagine that the last message was received at the time X, and the previous message\n was received at the time (X - 0.5 seconds); the period is 0.5 seconds, and therefore the publisher\n timeout is (0.5 seconds * 3) = 1.5 seconds. If there was no message from the current master in\n this amount of time, all slaves will synchronize with another master with the next-higher node-ID."
17923 )]
17924 pub const PUBLISHER_TIMEOUT_PERIOD_MULTIPLIER: u8 = 3;
17925 }
17926 impl ::emcyphal_encoding::Serialize for Synchronization {
17927 fn size_bits(&self) -> usize {
17928 56
17929 }
17930 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17931 cursor.write_u56(self.previous_transmission_timestamp_microsecond);
17932 }
17933 }
17934 impl ::emcyphal_encoding::Deserialize for Synchronization {
17935 fn deserialize(
17936 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17937 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17938 where
17939 Self: Sized,
17940 {
17941 Ok(Synchronization {
17942 previous_transmission_timestamp_microsecond: { cursor.read_u56() as _ },
17943 })
17944 }
17945 }
17946 }
17947 pub mod synchronized_timestamp_1_0 {
17948 #[cfg_attr(
17953 not(doctest),
17954 doc = " Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.\n This data type is highly recommended for use both in standard and vendor-specific messages alike."
17955 )]
17956 pub struct SynchronizedTimestamp {
17957 #[cfg_attr(
17958 not(doctest),
17959 doc = " The number of microseconds that have passed since some arbitrary moment in the past.\n The moment of origin (i.e., the time base) is defined per-application. The current time base in use\n can be requested from the time synchronization master, see the corresponding service definition.\n\n This value is to never overflow. The value is 56-bit wide because:\n\n - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be\n unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.\n\n - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.\n Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits."
17960 )]
17961 pub microsecond: u64,
17967 }
17968 impl ::emcyphal_encoding::DataType for SynchronizedTimestamp {
17969 const EXTENT_BYTES: Option<u32> = None;
17971 }
17972 impl ::emcyphal_encoding::Message for SynchronizedTimestamp {}
17973 impl ::emcyphal_encoding::BufferType for SynchronizedTimestamp {
17974 type Buffer = ::emcyphal_encoding::StaticBuffer<7>;
17975 }
17976 impl SynchronizedTimestamp {
17977 #[cfg_attr(not(doctest), doc = " Zero means that the time is not known.")]
17978 pub const UNKNOWN: u64 = 0;
17979 }
17980 impl ::emcyphal_encoding::Serialize for SynchronizedTimestamp {
17981 fn size_bits(&self) -> usize {
17982 56
17983 }
17984 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
17985 cursor.write_u56(self.microsecond);
17986 }
17987 }
17988 impl ::emcyphal_encoding::Deserialize for SynchronizedTimestamp {
17989 fn deserialize(
17990 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
17991 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
17992 where
17993 Self: Sized,
17994 {
17995 Ok(SynchronizedTimestamp {
17996 microsecond: { cursor.read_u56() as _ },
17997 })
17998 }
17999 }
18000 }
18001 pub mod tai_info_0_1 {
18002 #[cfg_attr(
18007 not(doctest),
18008 doc = " This data types defines constants and runtime values pertaining to the International Atomic Time, also known as TAI.\n See https://en.wikipedia.org/wiki/International_Atomic_Time.\n\n The relationship between the three major time systems -- TAI, GPS, and UTC -- is as follows:\n\n TAI = GPS + 19 seconds\n TAI = UTC + LS + 10 seconds\n\n Where \"LS\" is the current number of leap seconds: https://en.wikipedia.org/wiki/Leap_second.\n\n Cyphal applications should only rely on TAI whenever a global time system is needed.\n GPS time is strongly discouraged for reasons of consistency across different positioning systems and applications."
18009 )]
18010 pub struct TAIInfo {
18011 #[cfg_attr(
18012 not(doctest),
18013 doc = " The current difference between TAI and UTC, if known. If unknown, set to zero.\n\n This value may change states between known and unknown while the master is running,\n depending on its ability to obtain robust values from external sources.\n\n This value may change twice a year, possibly while the system is running; https://en.wikipedia.org/wiki/Leap_second.\n Since the rotation of Earth is decelerating, this value may only be positive. Do not use outside Earth.\n\n For reference, here is the full list of recorded TAI-UTC difference values, valid at the time of writing:\n\n Date | TAI-UTC difference [second]\n ----------|-----------------------------\n Jan 1972 | 10\n Jul 1972 | 11\n Jan 1973 | 12\n Jan 1974 | 13\n Jan 1975 | 14\n Jan 1976 | 15\n Jan 1977 | 16\n Jan 1978 | 17\n Jan 1979 | 18\n Jan 1980 | 19\n Jul 1981 | 20\n Jul 1982 | 21\n Jul 1983 | 22\n Jul 1985 | 23\n Jan 1988 | 24\n Jan 1990 | 25\n Jan 1991 | 26\n Jul 1992 | 27\n Jul 1993 | 28\n Jul 1994 | 29\n Jan 1996 | 30\n Jul 1997 | 31\n Jan 1999 | 32\n Jan 2006 | 33\n Jan 2009 | 34\n Jul 2012 | 35\n Jul 2015 | 36\n Jan 2017 | 37\n\n As of 2020, the future of the leap second and the relation between UTC and TAI remains uncertain."
18014 )]
18015 pub difference_tai_minus_utc: u16,
18021 }
18022 impl ::emcyphal_encoding::DataType for TAIInfo {
18023 const EXTENT_BYTES: Option<u32> = None;
18025 }
18026 impl ::emcyphal_encoding::Message for TAIInfo {}
18027 impl ::emcyphal_encoding::BufferType for TAIInfo {
18028 type Buffer = ::emcyphal_encoding::StaticBuffer<2>;
18029 }
18030 impl TAIInfo {
18031 #[cfg_attr(
18032 not(doctest),
18033 doc = " [second]\n The fixed difference, in seconds, between TAI and GPS time. Does not change ever.\n Systems that use GPS time as a reference should convert that to TAI by adding this difference."
18034 )]
18035 pub const DIFFERENCE_TAI_MINUS_GPS: u8 = 19;
18036 pub const DIFFERENCE_TAI_MINUS_UTC_UNKNOWN: u16 = 0;
18037 }
18038 impl ::emcyphal_encoding::Serialize for TAIInfo {
18039 fn size_bits(&self) -> usize {
18040 16
18041 }
18042 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
18043 cursor.write_u10(self.difference_tai_minus_utc);
18044 }
18045 }
18046 impl ::emcyphal_encoding::Deserialize for TAIInfo {
18047 fn deserialize(
18048 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
18049 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
18050 where
18051 Self: Sized,
18052 {
18053 Ok(TAIInfo {
18054 difference_tai_minus_utc: { cursor.read_u10() as _ },
18055 })
18056 }
18057 }
18058 }
18059 pub mod time_system_0_1 {
18060 #[cfg_attr(
18065 not(doctest),
18066 doc = " Time system enumeration.\n The time system shall be the same for all masters in the network.\n It cannot be changed while the network is running."
18067 )]
18068 pub struct TimeSystem {
18069 pub value: u8,
18075 }
18076 impl ::emcyphal_encoding::DataType for TimeSystem {
18077 const EXTENT_BYTES: Option<u32> = None;
18079 }
18080 impl ::emcyphal_encoding::Message for TimeSystem {}
18081 impl ::emcyphal_encoding::BufferType for TimeSystem {
18082 type Buffer = ::emcyphal_encoding::StaticBuffer<1>;
18083 }
18084 impl TimeSystem {
18085 #[cfg_attr(
18086 not(doctest),
18087 doc = " Monotonic time since boot.\n Monotonic time is a time reference that doesn't change rate or make leaps."
18088 )]
18089 pub const MONOTONIC_SINCE_BOOT: u8 = 0;
18090 #[cfg_attr(
18091 not(doctest),
18092 doc = " International Atomic Time; https://en.wikipedia.org/wiki/International_Atomic_Time.\n The timestamp value contains the number of microseconds elapsed since 1970-01-01T00:00:00Z TAI.\n TAI is always a fixed integer number of seconds ahead of GPS time.\n Systems that use GPS time as a reference should convert that to TAI by adding the fixed difference.\n GPS time is not supported for reasons of consistency across different positioning systems and applications."
18093 )]
18094 pub const TAI: u8 = 1;
18095 #[cfg_attr(
18096 not(doctest),
18097 doc = " Application-specific time system of unknown properties."
18098 )]
18099 pub const APPLICATION_SPECIFIC: u8 = 15;
18100 }
18101 impl ::emcyphal_encoding::Serialize for TimeSystem {
18102 fn size_bits(&self) -> usize {
18103 8
18104 }
18105 fn serialize(&self, cursor: &mut ::emcyphal_encoding::WriteCursor<'_>) {
18106 cursor.write_u4(self.value);
18107 }
18108 }
18109 impl ::emcyphal_encoding::Deserialize for TimeSystem {
18110 fn deserialize(
18111 cursor: &mut ::emcyphal_encoding::ReadCursor<'_>,
18112 ) -> ::core::result::Result<Self, ::emcyphal_encoding::DeserializeError>
18113 where
18114 Self: Sized,
18115 {
18116 Ok(TimeSystem {
18117 value: { cursor.read_u4() as _ },
18118 })
18119 }
18120 }
18121 }
18122 }
18123}