Skip to main content

sbp/messages/
system.rs

1// Copyright (C) 2015-2021 Swift Navigation Inc.
2// Contact: https://support.swiftnav.com
3//
4// This source is subject to the license found in the file 'LICENSE' which must
5// be distributed together with this source. All other rights reserved.
6//
7// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
8// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
9// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
10
11//****************************************************************************
12// Automatically generated from yaml/swiftnav/sbp/system.yaml
13// with generate.py. Please do not hand edit!
14//****************************************************************************/
15//! Standardized system messages from Swift Navigation devices.
16pub use msg_csac_telemetry::MsgCsacTelemetry;
17pub use msg_csac_telemetry_labels::MsgCsacTelemetryLabels;
18pub use msg_dgnss_status::MsgDgnssStatus;
19pub use msg_gnss_time_offset::MsgGnssTimeOffset;
20pub use msg_group_meta::MsgGroupMeta;
21pub use msg_heartbeat::MsgHeartbeat;
22pub use msg_ins_status::MsgInsStatus;
23pub use msg_ins_updates::MsgInsUpdates;
24pub use msg_pps_time::MsgPpsTime;
25pub use msg_sensor_aid_event::MsgSensorAidEvent;
26pub use msg_startup::MsgStartup;
27pub use msg_status_journal::MsgStatusJournal;
28pub use msg_status_report::MsgStatusReport;
29pub use status_journal_item::StatusJournalItem;
30pub use sub_system_report::SubSystemReport;
31
32pub mod msg_csac_telemetry {
33    #![allow(unused_imports)]
34
35    use super::*;
36    use crate::messages::lib::*;
37
38    /// Experimental telemetry message
39    ///
40    /// The CSAC telemetry message has an implementation defined telemetry string
41    /// from a device. It is not produced or available on general Swift Products.
42    /// It is intended to be a low rate message for status purposes.
43    ///
44    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
45    #[allow(clippy::derive_partial_eq_without_eq)]
46    #[derive(Debug, PartialEq, Clone)]
47    pub struct MsgCsacTelemetry {
48        /// The message sender_id
49        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
50        pub sender_id: Option<u16>,
51        /// Index representing the type of telemetry in use.  It is implementation
52        /// defined.
53        #[cfg_attr(feature = "serde", serde(rename = "id"))]
54        pub id: u8,
55        /// Comma separated list of values as defined by the index
56        #[cfg_attr(feature = "serde", serde(rename = "telemetry"))]
57        pub telemetry: SbpString<Vec<u8>, Unterminated>,
58    }
59
60    impl ConcreteMessage for MsgCsacTelemetry {
61        const MESSAGE_TYPE: u16 = 65284;
62        const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY";
63    }
64
65    impl SbpMessage for MsgCsacTelemetry {
66        fn message_name(&self) -> &'static str {
67            <Self as ConcreteMessage>::MESSAGE_NAME
68        }
69        fn message_type(&self) -> Option<u16> {
70            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
71        }
72        fn sender_id(&self) -> Option<u16> {
73            self.sender_id
74        }
75        fn set_sender_id(&mut self, new_id: u16) {
76            self.sender_id = Some(new_id);
77        }
78        fn encoded_len(&self) -> usize {
79            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
80        }
81        fn is_valid(&self) -> bool {
82            true
83        }
84        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
85            Ok(self)
86        }
87    }
88
89    impl FriendlyName for MsgCsacTelemetry {
90        fn friendly_name() -> &'static str {
91            "CSAC TELEMETRY"
92        }
93    }
94
95    impl TryFrom<Sbp> for MsgCsacTelemetry {
96        type Error = TryFromSbpError;
97        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
98            match msg {
99                Sbp::MsgCsacTelemetry(m) => Ok(m),
100                _ => Err(TryFromSbpError(msg)),
101            }
102        }
103    }
104
105    impl WireFormat for MsgCsacTelemetry {
106        const MIN_LEN: usize =
107            <u8 as WireFormat>::MIN_LEN + <SbpString<Vec<u8>, Unterminated> as WireFormat>::MIN_LEN;
108        fn len(&self) -> usize {
109            WireFormat::len(&self.id) + WireFormat::len(&self.telemetry)
110        }
111        fn write<B: BufMut>(&self, buf: &mut B) {
112            WireFormat::write(&self.id, buf);
113            WireFormat::write(&self.telemetry, buf);
114        }
115        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
116            MsgCsacTelemetry {
117                sender_id: None,
118                id: WireFormat::parse_unchecked(buf),
119                telemetry: WireFormat::parse_unchecked(buf),
120            }
121        }
122    }
123}
124
125pub mod msg_csac_telemetry_labels {
126    #![allow(unused_imports)]
127
128    use super::*;
129    use crate::messages::lib::*;
130
131    /// Experimental telemetry message labels
132    ///
133    /// The CSAC telemetry message provides labels for each member of the string
134    /// produced by MSG_CSAC_TELEMETRY. It should be provided by a device at a
135    /// lower rate than the MSG_CSAC_TELEMETRY.
136    ///
137    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138    #[allow(clippy::derive_partial_eq_without_eq)]
139    #[derive(Debug, PartialEq, Clone)]
140    pub struct MsgCsacTelemetryLabels {
141        /// The message sender_id
142        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
143        pub sender_id: Option<u16>,
144        /// Index representing the type of telemetry in use.  It is implementation
145        /// defined.
146        #[cfg_attr(feature = "serde", serde(rename = "id"))]
147        pub id: u8,
148        /// Comma separated list of telemetry field values
149        #[cfg_attr(feature = "serde", serde(rename = "telemetry_labels"))]
150        pub telemetry_labels: SbpString<Vec<u8>, Unterminated>,
151    }
152
153    impl ConcreteMessage for MsgCsacTelemetryLabels {
154        const MESSAGE_TYPE: u16 = 65285;
155        const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY_LABELS";
156    }
157
158    impl SbpMessage for MsgCsacTelemetryLabels {
159        fn message_name(&self) -> &'static str {
160            <Self as ConcreteMessage>::MESSAGE_NAME
161        }
162        fn message_type(&self) -> Option<u16> {
163            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
164        }
165        fn sender_id(&self) -> Option<u16> {
166            self.sender_id
167        }
168        fn set_sender_id(&mut self, new_id: u16) {
169            self.sender_id = Some(new_id);
170        }
171        fn encoded_len(&self) -> usize {
172            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
173        }
174        fn is_valid(&self) -> bool {
175            true
176        }
177        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
178            Ok(self)
179        }
180    }
181
182    impl FriendlyName for MsgCsacTelemetryLabels {
183        fn friendly_name() -> &'static str {
184            "CSAC TELEMETRY LABELS"
185        }
186    }
187
188    impl TryFrom<Sbp> for MsgCsacTelemetryLabels {
189        type Error = TryFromSbpError;
190        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
191            match msg {
192                Sbp::MsgCsacTelemetryLabels(m) => Ok(m),
193                _ => Err(TryFromSbpError(msg)),
194            }
195        }
196    }
197
198    impl WireFormat for MsgCsacTelemetryLabels {
199        const MIN_LEN: usize =
200            <u8 as WireFormat>::MIN_LEN + <SbpString<Vec<u8>, Unterminated> as WireFormat>::MIN_LEN;
201        fn len(&self) -> usize {
202            WireFormat::len(&self.id) + WireFormat::len(&self.telemetry_labels)
203        }
204        fn write<B: BufMut>(&self, buf: &mut B) {
205            WireFormat::write(&self.id, buf);
206            WireFormat::write(&self.telemetry_labels, buf);
207        }
208        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
209            MsgCsacTelemetryLabels {
210                sender_id: None,
211                id: WireFormat::parse_unchecked(buf),
212                telemetry_labels: WireFormat::parse_unchecked(buf),
213            }
214        }
215    }
216}
217
218pub mod msg_dgnss_status {
219    #![allow(unused_imports)]
220
221    use super::*;
222    use crate::messages::lib::*;
223
224    /// Status of received corrections
225    ///
226    /// This message provides information about the receipt of Differential
227    /// corrections.  It is expected to be sent with each receipt of a complete
228    /// corrections packet.
229    ///
230    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
231    #[allow(clippy::derive_partial_eq_without_eq)]
232    #[derive(Debug, PartialEq, Clone)]
233    pub struct MsgDgnssStatus {
234        /// The message sender_id
235        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
236        pub sender_id: Option<u16>,
237        /// Status flags
238        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
239        pub flags: u8,
240        /// Latency of observation receipt
241        #[cfg_attr(feature = "serde", serde(rename = "latency"))]
242        pub latency: u16,
243        /// Number of signals from base station
244        #[cfg_attr(feature = "serde", serde(rename = "num_signals"))]
245        pub num_signals: u8,
246        /// Corrections source string
247        #[cfg_attr(feature = "serde", serde(rename = "source"))]
248        pub source: SbpString<Vec<u8>, Unterminated>,
249    }
250
251    impl MsgDgnssStatus {
252        /// Gets the [DifferentialType][self::DifferentialType] stored in the `flags` bitfield.
253        ///
254        /// Returns `Ok` if the bitrange contains a known `DifferentialType` variant.
255        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
256        /// or because new variants of `DifferentialType` were added.
257        pub fn differential_type(&self) -> Result<DifferentialType, u8> {
258            get_bit_range!(self.flags, u8, u8, 3, 0).try_into()
259        }
260
261        /// Set the bitrange corresponding to the [DifferentialType][DifferentialType] of the `flags` bitfield.
262        pub fn set_differential_type(&mut self, differential_type: DifferentialType) {
263            set_bit_range!(&mut self.flags, differential_type, u8, u8, 3, 0);
264        }
265    }
266
267    impl ConcreteMessage for MsgDgnssStatus {
268        const MESSAGE_TYPE: u16 = 65282;
269        const MESSAGE_NAME: &'static str = "MSG_DGNSS_STATUS";
270    }
271
272    impl SbpMessage for MsgDgnssStatus {
273        fn message_name(&self) -> &'static str {
274            <Self as ConcreteMessage>::MESSAGE_NAME
275        }
276        fn message_type(&self) -> Option<u16> {
277            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
278        }
279        fn sender_id(&self) -> Option<u16> {
280            self.sender_id
281        }
282        fn set_sender_id(&mut self, new_id: u16) {
283            self.sender_id = Some(new_id);
284        }
285        fn encoded_len(&self) -> usize {
286            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
287        }
288        fn is_valid(&self) -> bool {
289            true
290        }
291        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
292            Ok(self)
293        }
294    }
295
296    impl FriendlyName for MsgDgnssStatus {
297        fn friendly_name() -> &'static str {
298            "DGNSS STATUS"
299        }
300    }
301
302    impl TryFrom<Sbp> for MsgDgnssStatus {
303        type Error = TryFromSbpError;
304        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
305            match msg {
306                Sbp::MsgDgnssStatus(m) => Ok(m),
307                _ => Err(TryFromSbpError(msg)),
308            }
309        }
310    }
311
312    impl WireFormat for MsgDgnssStatus {
313        const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
314            + <u16 as WireFormat>::MIN_LEN
315            + <u8 as WireFormat>::MIN_LEN
316            + <SbpString<Vec<u8>, Unterminated> as WireFormat>::MIN_LEN;
317        fn len(&self) -> usize {
318            WireFormat::len(&self.flags)
319                + WireFormat::len(&self.latency)
320                + WireFormat::len(&self.num_signals)
321                + WireFormat::len(&self.source)
322        }
323        fn write<B: BufMut>(&self, buf: &mut B) {
324            WireFormat::write(&self.flags, buf);
325            WireFormat::write(&self.latency, buf);
326            WireFormat::write(&self.num_signals, buf);
327            WireFormat::write(&self.source, buf);
328        }
329        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
330            MsgDgnssStatus {
331                sender_id: None,
332                flags: WireFormat::parse_unchecked(buf),
333                latency: WireFormat::parse_unchecked(buf),
334                num_signals: WireFormat::parse_unchecked(buf),
335                source: WireFormat::parse_unchecked(buf),
336            }
337        }
338    }
339
340    /// Differential type
341    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
342    pub enum DifferentialType {
343        /// Invalid
344        Invalid = 0,
345
346        /// Code Difference
347        CodeDifference = 1,
348
349        /// RTK
350        Rtk = 2,
351    }
352
353    impl std::fmt::Display for DifferentialType {
354        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
355            match self {
356                DifferentialType::Invalid => f.write_str("Invalid"),
357                DifferentialType::CodeDifference => f.write_str("Code Difference"),
358                DifferentialType::Rtk => f.write_str("RTK"),
359            }
360        }
361    }
362
363    impl TryFrom<u8> for DifferentialType {
364        type Error = u8;
365        fn try_from(i: u8) -> Result<Self, u8> {
366            match i {
367                0 => Ok(DifferentialType::Invalid),
368                1 => Ok(DifferentialType::CodeDifference),
369                2 => Ok(DifferentialType::Rtk),
370                i => Err(i),
371            }
372        }
373    }
374}
375
376pub mod msg_gnss_time_offset {
377    #![allow(unused_imports)]
378
379    use super::*;
380    use crate::messages::lib::*;
381
382    /// Offset of the local time with respect to GNSS time
383    ///
384    /// The GNSS time offset message contains the information that is needed to
385    /// translate messages tagged with a local timestamp (e.g. IMU or wheeltick
386    /// messages) to GNSS time for the sender producing this message.
387    ///
388    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
389    #[allow(clippy::derive_partial_eq_without_eq)]
390    #[derive(Debug, PartialEq, Clone)]
391    pub struct MsgGnssTimeOffset {
392        /// The message sender_id
393        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
394        pub sender_id: Option<u16>,
395        /// Weeks portion of the time offset
396        #[cfg_attr(feature = "serde", serde(rename = "weeks"))]
397        pub weeks: i16,
398        /// Milliseconds portion of the time offset
399        #[cfg_attr(feature = "serde", serde(rename = "milliseconds"))]
400        pub milliseconds: i32,
401        /// Microseconds portion of the time offset
402        #[cfg_attr(feature = "serde", serde(rename = "microseconds"))]
403        pub microseconds: i16,
404        /// Status flags
405        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
406        pub flags: u8,
407    }
408
409    impl MsgGnssTimeOffset {
410        /// Gets the `reserved_set_to_zero` stored in `flags`.
411        pub fn reserved_set_to_zero(&self) -> u8 {
412            get_bit_range!(self.flags, u8, u8, 7, 1)
413        }
414
415        /// Sets the `reserved_set_to_zero` bitrange of `flags`.
416        pub fn set_reserved_set_to_zero(&mut self, reserved_set_to_zero: u8) {
417            set_bit_range!(&mut self.flags, reserved_set_to_zero, u8, u8, 7, 1);
418        }
419
420        /// Gets the [WeeksBehavior][self::WeeksBehavior] stored in the `flags` bitfield.
421        ///
422        /// Returns `Ok` if the bitrange contains a known `WeeksBehavior` variant.
423        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
424        /// or because new variants of `WeeksBehavior` were added.
425        pub fn weeks_behavior(&self) -> Result<WeeksBehavior, u8> {
426            get_bit_range!(self.flags, u8, u8, 0, 0).try_into()
427        }
428
429        /// Set the bitrange corresponding to the [WeeksBehavior][WeeksBehavior] of the `flags` bitfield.
430        pub fn set_weeks_behavior(&mut self, weeks_behavior: WeeksBehavior) {
431            set_bit_range!(&mut self.flags, weeks_behavior, u8, u8, 0, 0);
432        }
433    }
434
435    impl ConcreteMessage for MsgGnssTimeOffset {
436        const MESSAGE_TYPE: u16 = 65287;
437        const MESSAGE_NAME: &'static str = "MSG_GNSS_TIME_OFFSET";
438    }
439
440    impl SbpMessage for MsgGnssTimeOffset {
441        fn message_name(&self) -> &'static str {
442            <Self as ConcreteMessage>::MESSAGE_NAME
443        }
444        fn message_type(&self) -> Option<u16> {
445            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
446        }
447        fn sender_id(&self) -> Option<u16> {
448            self.sender_id
449        }
450        fn set_sender_id(&mut self, new_id: u16) {
451            self.sender_id = Some(new_id);
452        }
453        fn encoded_len(&self) -> usize {
454            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
455        }
456        fn is_valid(&self) -> bool {
457            true
458        }
459        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
460            Ok(self)
461        }
462    }
463
464    impl FriendlyName for MsgGnssTimeOffset {
465        fn friendly_name() -> &'static str {
466            "GNSS TIME OFFSET"
467        }
468    }
469
470    impl TryFrom<Sbp> for MsgGnssTimeOffset {
471        type Error = TryFromSbpError;
472        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
473            match msg {
474                Sbp::MsgGnssTimeOffset(m) => Ok(m),
475                _ => Err(TryFromSbpError(msg)),
476            }
477        }
478    }
479
480    impl WireFormat for MsgGnssTimeOffset {
481        const MIN_LEN: usize = <i16 as WireFormat>::MIN_LEN
482            + <i32 as WireFormat>::MIN_LEN
483            + <i16 as WireFormat>::MIN_LEN
484            + <u8 as WireFormat>::MIN_LEN;
485        fn len(&self) -> usize {
486            WireFormat::len(&self.weeks)
487                + WireFormat::len(&self.milliseconds)
488                + WireFormat::len(&self.microseconds)
489                + WireFormat::len(&self.flags)
490        }
491        fn write<B: BufMut>(&self, buf: &mut B) {
492            WireFormat::write(&self.weeks, buf);
493            WireFormat::write(&self.milliseconds, buf);
494            WireFormat::write(&self.microseconds, buf);
495            WireFormat::write(&self.flags, buf);
496        }
497        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
498            MsgGnssTimeOffset {
499                sender_id: None,
500                weeks: WireFormat::parse_unchecked(buf),
501                milliseconds: WireFormat::parse_unchecked(buf),
502                microseconds: WireFormat::parse_unchecked(buf),
503                flags: WireFormat::parse_unchecked(buf),
504            }
505        }
506    }
507
508    /// Weeks behavior
509    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
510    pub enum WeeksBehavior {
511        /// Not affected on local timestamp rollover
512        NotAffectedOnLocalTimestampRollover = 0,
513
514        /// Incremented on local timestamp rollover
515        IncrementedOnLocalTimestampRollover = 1,
516    }
517
518    impl std::fmt::Display for WeeksBehavior {
519        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
520            match self {
521                WeeksBehavior::NotAffectedOnLocalTimestampRollover => {
522                    f.write_str("Not affected on local timestamp rollover")
523                }
524                WeeksBehavior::IncrementedOnLocalTimestampRollover => {
525                    f.write_str("Incremented on local timestamp rollover")
526                }
527            }
528        }
529    }
530
531    impl TryFrom<u8> for WeeksBehavior {
532        type Error = u8;
533        fn try_from(i: u8) -> Result<Self, u8> {
534            match i {
535                0 => Ok(WeeksBehavior::NotAffectedOnLocalTimestampRollover),
536                1 => Ok(WeeksBehavior::IncrementedOnLocalTimestampRollover),
537                i => Err(i),
538            }
539        }
540    }
541}
542
543pub mod msg_group_meta {
544    #![allow(unused_imports)]
545
546    use super::*;
547    use crate::messages::lib::*;
548
549    /// Solution Group Metadata
550    ///
551    /// This leading message lists the time metadata of the Solution Group. It
552    /// also lists the atomic contents (i.e. types of messages included) of the
553    /// Solution Group.
554    ///
555    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
556    #[allow(clippy::derive_partial_eq_without_eq)]
557    #[derive(Debug, PartialEq, Clone)]
558    pub struct MsgGroupMeta {
559        /// The message sender_id
560        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
561        pub sender_id: Option<u16>,
562        /// Id of the Msgs Group, 0 is Unknown, 1 is Bestpos, 2 is Gnss
563        #[cfg_attr(feature = "serde", serde(rename = "group_id"))]
564        pub group_id: u8,
565        /// Status flags (reserved)
566        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
567        pub flags: u8,
568        /// Size of list group_msgs
569        #[cfg_attr(feature = "serde", serde(rename = "n_group_msgs"))]
570        pub n_group_msgs: u8,
571        /// An in-order list of message types included in the Solution Group,
572        /// including GROUP_META itself
573        #[cfg_attr(feature = "serde", serde(rename = "group_msgs"))]
574        pub group_msgs: Vec<u16>,
575    }
576
577    impl MsgGroupMeta {
578        /// Gets the [SolutionGroupType][self::SolutionGroupType] stored in the `flags` bitfield.
579        ///
580        /// Returns `Ok` if the bitrange contains a known `SolutionGroupType` variant.
581        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
582        /// or because new variants of `SolutionGroupType` were added.
583        pub fn solution_group_type(&self) -> Result<SolutionGroupType, u8> {
584            get_bit_range!(self.flags, u8, u8, 1, 0).try_into()
585        }
586
587        /// Set the bitrange corresponding to the [SolutionGroupType][SolutionGroupType] of the `flags` bitfield.
588        pub fn set_solution_group_type(&mut self, solution_group_type: SolutionGroupType) {
589            set_bit_range!(&mut self.flags, solution_group_type, u8, u8, 1, 0);
590        }
591    }
592
593    impl ConcreteMessage for MsgGroupMeta {
594        const MESSAGE_TYPE: u16 = 65290;
595        const MESSAGE_NAME: &'static str = "MSG_GROUP_META";
596    }
597
598    impl SbpMessage for MsgGroupMeta {
599        fn message_name(&self) -> &'static str {
600            <Self as ConcreteMessage>::MESSAGE_NAME
601        }
602        fn message_type(&self) -> Option<u16> {
603            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
604        }
605        fn sender_id(&self) -> Option<u16> {
606            self.sender_id
607        }
608        fn set_sender_id(&mut self, new_id: u16) {
609            self.sender_id = Some(new_id);
610        }
611        fn encoded_len(&self) -> usize {
612            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
613        }
614        fn is_valid(&self) -> bool {
615            true
616        }
617        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
618            Ok(self)
619        }
620    }
621
622    impl FriendlyName for MsgGroupMeta {
623        fn friendly_name() -> &'static str {
624            "GROUP META"
625        }
626    }
627
628    impl TryFrom<Sbp> for MsgGroupMeta {
629        type Error = TryFromSbpError;
630        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
631            match msg {
632                Sbp::MsgGroupMeta(m) => Ok(m),
633                _ => Err(TryFromSbpError(msg)),
634            }
635        }
636    }
637
638    impl WireFormat for MsgGroupMeta {
639        const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
640            + <u8 as WireFormat>::MIN_LEN
641            + <u8 as WireFormat>::MIN_LEN
642            + <Vec<u16> as WireFormat>::MIN_LEN;
643        fn len(&self) -> usize {
644            WireFormat::len(&self.group_id)
645                + WireFormat::len(&self.flags)
646                + WireFormat::len(&self.n_group_msgs)
647                + WireFormat::len(&self.group_msgs)
648        }
649        fn write<B: BufMut>(&self, buf: &mut B) {
650            WireFormat::write(&self.group_id, buf);
651            WireFormat::write(&self.flags, buf);
652            WireFormat::write(&self.n_group_msgs, buf);
653            WireFormat::write(&self.group_msgs, buf);
654        }
655        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
656            MsgGroupMeta {
657                sender_id: None,
658                group_id: WireFormat::parse_unchecked(buf),
659                flags: WireFormat::parse_unchecked(buf),
660                n_group_msgs: WireFormat::parse_unchecked(buf),
661                group_msgs: WireFormat::parse_unchecked(buf),
662            }
663        }
664    }
665
666    /// Solution Group type
667    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
668    pub enum SolutionGroupType {
669        /// None (invalid)
670        None = 0,
671
672        /// GNSS only
673        GnssOnly = 1,
674
675        /// GNSS+INS (Fuzed)
676        Gnssins = 2,
677    }
678
679    impl std::fmt::Display for SolutionGroupType {
680        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
681            match self {
682                SolutionGroupType::None => f.write_str("None (invalid)"),
683                SolutionGroupType::GnssOnly => f.write_str("GNSS only"),
684                SolutionGroupType::Gnssins => f.write_str("GNSS+INS (Fuzed)"),
685            }
686        }
687    }
688
689    impl TryFrom<u8> for SolutionGroupType {
690        type Error = u8;
691        fn try_from(i: u8) -> Result<Self, u8> {
692            match i {
693                0 => Ok(SolutionGroupType::None),
694                1 => Ok(SolutionGroupType::GnssOnly),
695                2 => Ok(SolutionGroupType::Gnssins),
696                i => Err(i),
697            }
698        }
699    }
700}
701
702pub mod msg_heartbeat {
703    #![allow(unused_imports)]
704
705    use super::*;
706    use crate::messages::lib::*;
707
708    /// System heartbeat message
709    ///
710    /// The heartbeat message is sent periodically to inform the host or other
711    /// attached devices that the system is running. It is used to monitor system
712    /// malfunctions. It also contains status flags that indicate to the host the
713    /// status of the system and whether it is operating correctly. Currently, the
714    /// expected heartbeat interval is 1 sec.
715    ///
716    /// The system error flag is used to indicate that an error has occurred in
717    /// the system. To determine the source of the error, the remaining error
718    /// flags should be inspected.
719    ///
720    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
721    #[allow(clippy::derive_partial_eq_without_eq)]
722    #[derive(Debug, PartialEq, Clone)]
723    pub struct MsgHeartbeat {
724        /// The message sender_id
725        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
726        pub sender_id: Option<u16>,
727        /// Status flags
728        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
729        pub flags: u32,
730    }
731
732    impl MsgHeartbeat {
733        /// Gets the [ExternalAntennaPresent][self::ExternalAntennaPresent] stored in the `flags` bitfield.
734        ///
735        /// Returns `Ok` if the bitrange contains a known `ExternalAntennaPresent` variant.
736        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
737        /// or because new variants of `ExternalAntennaPresent` were added.
738        pub fn external_antenna_present(&self) -> Result<ExternalAntennaPresent, u8> {
739            get_bit_range!(self.flags, u32, u8, 31, 31).try_into()
740        }
741
742        /// Set the bitrange corresponding to the [ExternalAntennaPresent][ExternalAntennaPresent] of the `flags` bitfield.
743        pub fn set_external_antenna_present(
744            &mut self,
745            external_antenna_present: ExternalAntennaPresent,
746        ) {
747            set_bit_range!(&mut self.flags, external_antenna_present, u32, u8, 31, 31);
748        }
749
750        /// Gets the [ExternalAntennaShort][self::ExternalAntennaShort] stored in the `flags` bitfield.
751        ///
752        /// Returns `Ok` if the bitrange contains a known `ExternalAntennaShort` variant.
753        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
754        /// or because new variants of `ExternalAntennaShort` were added.
755        pub fn external_antenna_short(&self) -> Result<ExternalAntennaShort, u8> {
756            get_bit_range!(self.flags, u32, u8, 30, 30).try_into()
757        }
758
759        /// Set the bitrange corresponding to the [ExternalAntennaShort][ExternalAntennaShort] of the `flags` bitfield.
760        pub fn set_external_antenna_short(&mut self, external_antenna_short: ExternalAntennaShort) {
761            set_bit_range!(&mut self.flags, external_antenna_short, u32, u8, 30, 30);
762        }
763
764        /// Gets the `sbp_major_protocol_version_number` stored in `flags`.
765        pub fn sbp_major_protocol_version_number(&self) -> u8 {
766            get_bit_range!(self.flags, u32, u8, 23, 16)
767        }
768
769        /// Sets the `sbp_major_protocol_version_number` bitrange of `flags`.
770        pub fn set_sbp_major_protocol_version_number(
771            &mut self,
772            sbp_major_protocol_version_number: u8,
773        ) {
774            set_bit_range!(
775                &mut self.flags,
776                sbp_major_protocol_version_number,
777                u32,
778                u8,
779                23,
780                16
781            );
782        }
783
784        /// Gets the `sbp_minor_protocol_version_number` stored in `flags`.
785        pub fn sbp_minor_protocol_version_number(&self) -> u8 {
786            get_bit_range!(self.flags, u32, u8, 15, 8)
787        }
788
789        /// Sets the `sbp_minor_protocol_version_number` bitrange of `flags`.
790        pub fn set_sbp_minor_protocol_version_number(
791            &mut self,
792            sbp_minor_protocol_version_number: u8,
793        ) {
794            set_bit_range!(
795                &mut self.flags,
796                sbp_minor_protocol_version_number,
797                u32,
798                u8,
799                15,
800                8
801            );
802        }
803
804        /// Gets the [SwiftNapError][self::SwiftNapError] stored in the `flags` bitfield.
805        ///
806        /// Returns `Ok` if the bitrange contains a known `SwiftNapError` variant.
807        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
808        /// or because new variants of `SwiftNapError` were added.
809        pub fn swift_nap_error(&self) -> Result<SwiftNapError, u8> {
810            get_bit_range!(self.flags, u32, u8, 2, 2).try_into()
811        }
812
813        /// Set the bitrange corresponding to the [SwiftNapError][SwiftNapError] of the `flags` bitfield.
814        pub fn set_swift_nap_error(&mut self, swift_nap_error: SwiftNapError) {
815            set_bit_range!(&mut self.flags, swift_nap_error, u32, u8, 2, 2);
816        }
817
818        /// Gets the [IoError][self::IoError] stored in the `flags` bitfield.
819        ///
820        /// Returns `Ok` if the bitrange contains a known `IoError` variant.
821        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
822        /// or because new variants of `IoError` were added.
823        pub fn io_error(&self) -> Result<IoError, u8> {
824            get_bit_range!(self.flags, u32, u8, 1, 1).try_into()
825        }
826
827        /// Set the bitrange corresponding to the [IoError][IoError] of the `flags` bitfield.
828        pub fn set_io_error(&mut self, io_error: IoError) {
829            set_bit_range!(&mut self.flags, io_error, u32, u8, 1, 1);
830        }
831
832        /// Gets the [SystemErrorFlag][self::SystemErrorFlag] stored in the `flags` bitfield.
833        ///
834        /// Returns `Ok` if the bitrange contains a known `SystemErrorFlag` variant.
835        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
836        /// or because new variants of `SystemErrorFlag` were added.
837        pub fn system_error_flag(&self) -> Result<SystemErrorFlag, u8> {
838            get_bit_range!(self.flags, u32, u8, 0, 0).try_into()
839        }
840
841        /// Set the bitrange corresponding to the [SystemErrorFlag][SystemErrorFlag] of the `flags` bitfield.
842        pub fn set_system_error_flag(&mut self, system_error_flag: SystemErrorFlag) {
843            set_bit_range!(&mut self.flags, system_error_flag, u32, u8, 0, 0);
844        }
845    }
846
847    impl ConcreteMessage for MsgHeartbeat {
848        const MESSAGE_TYPE: u16 = 65535;
849        const MESSAGE_NAME: &'static str = "MSG_HEARTBEAT";
850    }
851
852    impl SbpMessage for MsgHeartbeat {
853        fn message_name(&self) -> &'static str {
854            <Self as ConcreteMessage>::MESSAGE_NAME
855        }
856        fn message_type(&self) -> Option<u16> {
857            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
858        }
859        fn sender_id(&self) -> Option<u16> {
860            self.sender_id
861        }
862        fn set_sender_id(&mut self, new_id: u16) {
863            self.sender_id = Some(new_id);
864        }
865        fn encoded_len(&self) -> usize {
866            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
867        }
868        fn is_valid(&self) -> bool {
869            true
870        }
871        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
872            Ok(self)
873        }
874    }
875
876    impl FriendlyName for MsgHeartbeat {
877        fn friendly_name() -> &'static str {
878            "HEARTBEAT"
879        }
880    }
881
882    impl TryFrom<Sbp> for MsgHeartbeat {
883        type Error = TryFromSbpError;
884        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
885            match msg {
886                Sbp::MsgHeartbeat(m) => Ok(m),
887                _ => Err(TryFromSbpError(msg)),
888            }
889        }
890    }
891
892    impl WireFormat for MsgHeartbeat {
893        const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN;
894        fn len(&self) -> usize {
895            WireFormat::len(&self.flags)
896        }
897        fn write<B: BufMut>(&self, buf: &mut B) {
898            WireFormat::write(&self.flags, buf);
899        }
900        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
901            MsgHeartbeat {
902                sender_id: None,
903                flags: WireFormat::parse_unchecked(buf),
904            }
905        }
906    }
907
908    /// External antenna present
909    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
910    pub enum ExternalAntennaPresent {
911        /// No external antenna detected
912        NoExternalAntennaDetected = 0,
913
914        /// External antenna is present
915        ExternalAntennaIsPresent = 1,
916    }
917
918    impl std::fmt::Display for ExternalAntennaPresent {
919        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
920            match self {
921                ExternalAntennaPresent::NoExternalAntennaDetected => {
922                    f.write_str("No external antenna detected")
923                }
924                ExternalAntennaPresent::ExternalAntennaIsPresent => {
925                    f.write_str("External antenna is present")
926                }
927            }
928        }
929    }
930
931    impl TryFrom<u8> for ExternalAntennaPresent {
932        type Error = u8;
933        fn try_from(i: u8) -> Result<Self, u8> {
934            match i {
935                0 => Ok(ExternalAntennaPresent::NoExternalAntennaDetected),
936                1 => Ok(ExternalAntennaPresent::ExternalAntennaIsPresent),
937                i => Err(i),
938            }
939        }
940    }
941
942    /// External antenna short
943    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
944    pub enum ExternalAntennaShort {
945        /// No short detected
946        NoShortDetected = 0,
947
948        /// Short detected
949        ShortDetected = 1,
950    }
951
952    impl std::fmt::Display for ExternalAntennaShort {
953        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
954            match self {
955                ExternalAntennaShort::NoShortDetected => f.write_str("No short detected"),
956                ExternalAntennaShort::ShortDetected => f.write_str("Short detected"),
957            }
958        }
959    }
960
961    impl TryFrom<u8> for ExternalAntennaShort {
962        type Error = u8;
963        fn try_from(i: u8) -> Result<Self, u8> {
964            match i {
965                0 => Ok(ExternalAntennaShort::NoShortDetected),
966                1 => Ok(ExternalAntennaShort::ShortDetected),
967                i => Err(i),
968            }
969        }
970    }
971
972    /// SwiftNAP Error
973    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
974    pub enum SwiftNapError {
975        /// System Healthy
976        SystemHealthy = 0,
977
978        /// An error has occurred in the SwiftNAP
979        AnErrorHasOccurredInTheSwiftNap = 1,
980    }
981
982    impl std::fmt::Display for SwiftNapError {
983        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
984            match self {
985                SwiftNapError::SystemHealthy => f.write_str("System Healthy"),
986                SwiftNapError::AnErrorHasOccurredInTheSwiftNap => {
987                    f.write_str("An error has occurred in the SwiftNAP")
988                }
989            }
990        }
991    }
992
993    impl TryFrom<u8> for SwiftNapError {
994        type Error = u8;
995        fn try_from(i: u8) -> Result<Self, u8> {
996            match i {
997                0 => Ok(SwiftNapError::SystemHealthy),
998                1 => Ok(SwiftNapError::AnErrorHasOccurredInTheSwiftNap),
999                i => Err(i),
1000            }
1001        }
1002    }
1003
1004    /// IO Error
1005    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1006    pub enum IoError {
1007        /// System Healthy
1008        SystemHealthy = 0,
1009
1010        /// An IO error has occurred
1011        AnIoErrorHasOccurred = 1,
1012    }
1013
1014    impl std::fmt::Display for IoError {
1015        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1016            match self {
1017                IoError::SystemHealthy => f.write_str("System Healthy"),
1018                IoError::AnIoErrorHasOccurred => f.write_str("An IO error has occurred"),
1019            }
1020        }
1021    }
1022
1023    impl TryFrom<u8> for IoError {
1024        type Error = u8;
1025        fn try_from(i: u8) -> Result<Self, u8> {
1026            match i {
1027                0 => Ok(IoError::SystemHealthy),
1028                1 => Ok(IoError::AnIoErrorHasOccurred),
1029                i => Err(i),
1030            }
1031        }
1032    }
1033
1034    /// System Error Flag
1035    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1036    pub enum SystemErrorFlag {
1037        /// System Healthy
1038        SystemHealthy = 0,
1039
1040        /// An error has occurred
1041        AnErrorHasOccurred = 1,
1042    }
1043
1044    impl std::fmt::Display for SystemErrorFlag {
1045        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1046            match self {
1047                SystemErrorFlag::SystemHealthy => f.write_str("System Healthy"),
1048                SystemErrorFlag::AnErrorHasOccurred => f.write_str("An error has occurred"),
1049            }
1050        }
1051    }
1052
1053    impl TryFrom<u8> for SystemErrorFlag {
1054        type Error = u8;
1055        fn try_from(i: u8) -> Result<Self, u8> {
1056            match i {
1057                0 => Ok(SystemErrorFlag::SystemHealthy),
1058                1 => Ok(SystemErrorFlag::AnErrorHasOccurred),
1059                i => Err(i),
1060            }
1061        }
1062    }
1063}
1064
1065pub mod msg_ins_status {
1066    #![allow(unused_imports)]
1067
1068    use super::*;
1069    use crate::messages::lib::*;
1070
1071    /// Inertial Navigation System status message
1072    ///
1073    /// The INS status message describes the state of the operation and
1074    /// initialization of the inertial navigation system.
1075    ///
1076    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1077    #[allow(clippy::derive_partial_eq_without_eq)]
1078    #[derive(Debug, PartialEq, Clone)]
1079    pub struct MsgInsStatus {
1080        /// The message sender_id
1081        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1082        pub sender_id: Option<u16>,
1083        /// Status flags
1084        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1085        pub flags: u32,
1086    }
1087
1088    impl MsgInsStatus {
1089        /// Gets the [InsType][self::InsType] stored in the `flags` bitfield.
1090        ///
1091        /// Returns `Ok` if the bitrange contains a known `InsType` variant.
1092        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1093        /// or because new variants of `InsType` were added.
1094        pub fn ins_type(&self) -> Result<InsType, u8> {
1095            get_bit_range!(self.flags, u32, u8, 31, 29).try_into()
1096        }
1097
1098        /// Set the bitrange corresponding to the [InsType][InsType] of the `flags` bitfield.
1099        pub fn set_ins_type(&mut self, ins_type: InsType) {
1100            set_bit_range!(&mut self.flags, ins_type, u32, u8, 31, 29);
1101        }
1102
1103        /// Gets the [MotionState][self::MotionState] stored in the `flags` bitfield.
1104        ///
1105        /// Returns `Ok` if the bitrange contains a known `MotionState` variant.
1106        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1107        /// or because new variants of `MotionState` were added.
1108        pub fn motion_state(&self) -> Result<MotionState, u8> {
1109            get_bit_range!(self.flags, u32, u8, 13, 11).try_into()
1110        }
1111
1112        /// Set the bitrange corresponding to the [MotionState][MotionState] of the `flags` bitfield.
1113        pub fn set_motion_state(&mut self, motion_state: MotionState) {
1114            set_bit_range!(&mut self.flags, motion_state, u32, u8, 13, 11);
1115        }
1116
1117        /// Gets the [OdometrySynch][self::OdometrySynch] stored in the `flags` bitfield.
1118        ///
1119        /// Returns `Ok` if the bitrange contains a known `OdometrySynch` variant.
1120        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1121        /// or because new variants of `OdometrySynch` were added.
1122        pub fn odometry_synch(&self) -> Result<OdometrySynch, u8> {
1123            get_bit_range!(self.flags, u32, u8, 10, 10).try_into()
1124        }
1125
1126        /// Set the bitrange corresponding to the [OdometrySynch][OdometrySynch] of the `flags` bitfield.
1127        pub fn set_odometry_synch(&mut self, odometry_synch: OdometrySynch) {
1128            set_bit_range!(&mut self.flags, odometry_synch, u32, u8, 10, 10);
1129        }
1130
1131        /// Gets the [OdometryStatus][self::OdometryStatus] stored in the `flags` bitfield.
1132        ///
1133        /// Returns `Ok` if the bitrange contains a known `OdometryStatus` variant.
1134        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1135        /// or because new variants of `OdometryStatus` were added.
1136        pub fn odometry_status(&self) -> Result<OdometryStatus, u8> {
1137            get_bit_range!(self.flags, u32, u8, 9, 8).try_into()
1138        }
1139
1140        /// Set the bitrange corresponding to the [OdometryStatus][OdometryStatus] of the `flags` bitfield.
1141        pub fn set_odometry_status(&mut self, odometry_status: OdometryStatus) {
1142            set_bit_range!(&mut self.flags, odometry_status, u32, u8, 9, 8);
1143        }
1144
1145        /// Gets the [InsError][self::InsError] stored in the `flags` bitfield.
1146        ///
1147        /// Returns `Ok` if the bitrange contains a known `InsError` variant.
1148        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1149        /// or because new variants of `InsError` were added.
1150        pub fn ins_error(&self) -> Result<InsError, u8> {
1151            get_bit_range!(self.flags, u32, u8, 7, 4).try_into()
1152        }
1153
1154        /// Set the bitrange corresponding to the [InsError][InsError] of the `flags` bitfield.
1155        pub fn set_ins_error(&mut self, ins_error: InsError) {
1156            set_bit_range!(&mut self.flags, ins_error, u32, u8, 7, 4);
1157        }
1158
1159        /// Gets the [GnssFix][self::GnssFix] stored in the `flags` bitfield.
1160        ///
1161        /// Returns `Ok` if the bitrange contains a known `GnssFix` variant.
1162        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1163        /// or because new variants of `GnssFix` were added.
1164        pub fn gnss_fix(&self) -> Result<GnssFix, u8> {
1165            get_bit_range!(self.flags, u32, u8, 3, 3).try_into()
1166        }
1167
1168        /// Set the bitrange corresponding to the [GnssFix][GnssFix] of the `flags` bitfield.
1169        pub fn set_gnss_fix(&mut self, gnss_fix: GnssFix) {
1170            set_bit_range!(&mut self.flags, gnss_fix, u32, u8, 3, 3);
1171        }
1172
1173        /// Gets the [Mode][self::Mode] stored in the `flags` bitfield.
1174        ///
1175        /// Returns `Ok` if the bitrange contains a known `Mode` variant.
1176        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1177        /// or because new variants of `Mode` were added.
1178        pub fn mode(&self) -> Result<Mode, u8> {
1179            get_bit_range!(self.flags, u32, u8, 2, 0).try_into()
1180        }
1181
1182        /// Set the bitrange corresponding to the [Mode][Mode] of the `flags` bitfield.
1183        pub fn set_mode(&mut self, mode: Mode) {
1184            set_bit_range!(&mut self.flags, mode, u32, u8, 2, 0);
1185        }
1186    }
1187
1188    impl ConcreteMessage for MsgInsStatus {
1189        const MESSAGE_TYPE: u16 = 65283;
1190        const MESSAGE_NAME: &'static str = "MSG_INS_STATUS";
1191    }
1192
1193    impl SbpMessage for MsgInsStatus {
1194        fn message_name(&self) -> &'static str {
1195            <Self as ConcreteMessage>::MESSAGE_NAME
1196        }
1197        fn message_type(&self) -> Option<u16> {
1198            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1199        }
1200        fn sender_id(&self) -> Option<u16> {
1201            self.sender_id
1202        }
1203        fn set_sender_id(&mut self, new_id: u16) {
1204            self.sender_id = Some(new_id);
1205        }
1206        fn encoded_len(&self) -> usize {
1207            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1208        }
1209        fn is_valid(&self) -> bool {
1210            true
1211        }
1212        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1213            Ok(self)
1214        }
1215    }
1216
1217    impl FriendlyName for MsgInsStatus {
1218        fn friendly_name() -> &'static str {
1219            "INS STATUS"
1220        }
1221    }
1222
1223    impl TryFrom<Sbp> for MsgInsStatus {
1224        type Error = TryFromSbpError;
1225        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1226            match msg {
1227                Sbp::MsgInsStatus(m) => Ok(m),
1228                _ => Err(TryFromSbpError(msg)),
1229            }
1230        }
1231    }
1232
1233    impl WireFormat for MsgInsStatus {
1234        const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN;
1235        fn len(&self) -> usize {
1236            WireFormat::len(&self.flags)
1237        }
1238        fn write<B: BufMut>(&self, buf: &mut B) {
1239            WireFormat::write(&self.flags, buf);
1240        }
1241        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1242            MsgInsStatus {
1243                sender_id: None,
1244                flags: WireFormat::parse_unchecked(buf),
1245            }
1246        }
1247    }
1248
1249    /// INS Type
1250    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1251    pub enum InsType {
1252        /// Smoothpose Loosely Coupled
1253        SmoothposeLooselyCoupled = 0,
1254
1255        /// Starling
1256        Starling = 1,
1257    }
1258
1259    impl std::fmt::Display for InsType {
1260        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1261            match self {
1262                InsType::SmoothposeLooselyCoupled => f.write_str("Smoothpose Loosely Coupled"),
1263                InsType::Starling => f.write_str("Starling"),
1264            }
1265        }
1266    }
1267
1268    impl TryFrom<u8> for InsType {
1269        type Error = u8;
1270        fn try_from(i: u8) -> Result<Self, u8> {
1271            match i {
1272                0 => Ok(InsType::SmoothposeLooselyCoupled),
1273                1 => Ok(InsType::Starling),
1274                i => Err(i),
1275            }
1276        }
1277    }
1278
1279    /// Motion State
1280    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1281    pub enum MotionState {
1282        /// Unknown or Init
1283        UnknownOrInit = 0,
1284
1285        /// Arbitrary Motion
1286        ArbitraryMotion = 1,
1287
1288        /// Straight Motion
1289        StraightMotion = 2,
1290
1291        /// Stationary
1292        Stationary = 3,
1293    }
1294
1295    impl std::fmt::Display for MotionState {
1296        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1297            match self {
1298                MotionState::UnknownOrInit => f.write_str("Unknown or Init"),
1299                MotionState::ArbitraryMotion => f.write_str("Arbitrary Motion"),
1300                MotionState::StraightMotion => f.write_str("Straight Motion"),
1301                MotionState::Stationary => f.write_str("Stationary"),
1302            }
1303        }
1304    }
1305
1306    impl TryFrom<u8> for MotionState {
1307        type Error = u8;
1308        fn try_from(i: u8) -> Result<Self, u8> {
1309            match i {
1310                0 => Ok(MotionState::UnknownOrInit),
1311                1 => Ok(MotionState::ArbitraryMotion),
1312                2 => Ok(MotionState::StraightMotion),
1313                3 => Ok(MotionState::Stationary),
1314                i => Err(i),
1315            }
1316        }
1317    }
1318
1319    /// Odometry Synch
1320    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1321    pub enum OdometrySynch {
1322        /// Odometry timestamp nominal
1323        OdometryTimestampNominal = 0,
1324
1325        /// Odometry timestamp out of bounds
1326        OdometryTimestampOutOfBounds = 1,
1327    }
1328
1329    impl std::fmt::Display for OdometrySynch {
1330        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1331            match self {
1332                OdometrySynch::OdometryTimestampNominal => {
1333                    f.write_str("Odometry timestamp nominal")
1334                }
1335                OdometrySynch::OdometryTimestampOutOfBounds => {
1336                    f.write_str("Odometry timestamp out of bounds")
1337                }
1338            }
1339        }
1340    }
1341
1342    impl TryFrom<u8> for OdometrySynch {
1343        type Error = u8;
1344        fn try_from(i: u8) -> Result<Self, u8> {
1345            match i {
1346                0 => Ok(OdometrySynch::OdometryTimestampNominal),
1347                1 => Ok(OdometrySynch::OdometryTimestampOutOfBounds),
1348                i => Err(i),
1349            }
1350        }
1351    }
1352
1353    /// Odometry status
1354    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1355    pub enum OdometryStatus {
1356        /// No Odometry
1357        NoOdometry = 0,
1358
1359        /// Odometry received within last second
1360        OdometryReceivedWithinLastSecond = 1,
1361
1362        /// Odometry not received within last second
1363        OdometryNotReceivedWithinLastSecond = 2,
1364    }
1365
1366    impl std::fmt::Display for OdometryStatus {
1367        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1368            match self {
1369                OdometryStatus::NoOdometry => f.write_str("No Odometry"),
1370                OdometryStatus::OdometryReceivedWithinLastSecond => {
1371                    f.write_str("Odometry received within last second")
1372                }
1373                OdometryStatus::OdometryNotReceivedWithinLastSecond => {
1374                    f.write_str("Odometry not received within last second")
1375                }
1376            }
1377        }
1378    }
1379
1380    impl TryFrom<u8> for OdometryStatus {
1381        type Error = u8;
1382        fn try_from(i: u8) -> Result<Self, u8> {
1383            match i {
1384                0 => Ok(OdometryStatus::NoOdometry),
1385                1 => Ok(OdometryStatus::OdometryReceivedWithinLastSecond),
1386                2 => Ok(OdometryStatus::OdometryNotReceivedWithinLastSecond),
1387                i => Err(i),
1388            }
1389        }
1390    }
1391
1392    /// INS Error
1393    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1394    pub enum InsError {
1395        /// IMU Data Error
1396        ImuDataError = 1,
1397
1398        /// INS License Error
1399        InsLicenseError = 2,
1400
1401        /// IMU Calibration Data Error
1402        ImuCalibrationDataError = 3,
1403    }
1404
1405    impl std::fmt::Display for InsError {
1406        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1407            match self {
1408                InsError::ImuDataError => f.write_str("IMU Data Error"),
1409                InsError::InsLicenseError => f.write_str("INS License Error"),
1410                InsError::ImuCalibrationDataError => f.write_str("IMU Calibration Data Error"),
1411            }
1412        }
1413    }
1414
1415    impl TryFrom<u8> for InsError {
1416        type Error = u8;
1417        fn try_from(i: u8) -> Result<Self, u8> {
1418            match i {
1419                1 => Ok(InsError::ImuDataError),
1420                2 => Ok(InsError::InsLicenseError),
1421                3 => Ok(InsError::ImuCalibrationDataError),
1422                i => Err(i),
1423            }
1424        }
1425    }
1426
1427    /// GNSS Fix
1428    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1429    pub enum GnssFix {
1430        /// No GNSS fix available
1431        NoGnssFixAvailable = 0,
1432
1433        /// GNSS fix
1434        GnssFix = 1,
1435    }
1436
1437    impl std::fmt::Display for GnssFix {
1438        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1439            match self {
1440                GnssFix::NoGnssFixAvailable => f.write_str("No GNSS fix available"),
1441                GnssFix::GnssFix => f.write_str("GNSS fix"),
1442            }
1443        }
1444    }
1445
1446    impl TryFrom<u8> for GnssFix {
1447        type Error = u8;
1448        fn try_from(i: u8) -> Result<Self, u8> {
1449            match i {
1450                0 => Ok(GnssFix::NoGnssFixAvailable),
1451                1 => Ok(GnssFix::GnssFix),
1452                i => Err(i),
1453            }
1454        }
1455    }
1456
1457    /// Mode
1458    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1459    pub enum Mode {
1460        /// Awaiting initialization
1461        AwaitingInitialization = 0,
1462
1463        /// Dynamically aligning
1464        DynamicallyAligning = 1,
1465
1466        /// Ready
1467        Ready = 2,
1468
1469        /// GNSS Outage exceeds max duration
1470        GnssOutageExceedsMaxDuration = 3,
1471
1472        /// FastStart seeding
1473        FastStartSeeding = 4,
1474
1475        /// FastStart validating
1476        FastStartValidating = 5,
1477
1478        /// Validating unsafe fast start seed
1479        ValidatingUnsafeFastStartSeed = 6,
1480    }
1481
1482    impl std::fmt::Display for Mode {
1483        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1484            match self {
1485                Mode::AwaitingInitialization => f.write_str("Awaiting initialization"),
1486                Mode::DynamicallyAligning => f.write_str("Dynamically aligning"),
1487                Mode::Ready => f.write_str("Ready"),
1488                Mode::GnssOutageExceedsMaxDuration => {
1489                    f.write_str("GNSS Outage exceeds max duration")
1490                }
1491                Mode::FastStartSeeding => f.write_str("FastStart seeding"),
1492                Mode::FastStartValidating => f.write_str("FastStart validating"),
1493                Mode::ValidatingUnsafeFastStartSeed => {
1494                    f.write_str("Validating unsafe fast start seed")
1495                }
1496            }
1497        }
1498    }
1499
1500    impl TryFrom<u8> for Mode {
1501        type Error = u8;
1502        fn try_from(i: u8) -> Result<Self, u8> {
1503            match i {
1504                0 => Ok(Mode::AwaitingInitialization),
1505                1 => Ok(Mode::DynamicallyAligning),
1506                2 => Ok(Mode::Ready),
1507                3 => Ok(Mode::GnssOutageExceedsMaxDuration),
1508                4 => Ok(Mode::FastStartSeeding),
1509                5 => Ok(Mode::FastStartValidating),
1510                6 => Ok(Mode::ValidatingUnsafeFastStartSeed),
1511                i => Err(i),
1512            }
1513        }
1514    }
1515}
1516
1517pub mod msg_ins_updates {
1518    #![allow(unused_imports)]
1519
1520    use super::*;
1521    use crate::messages::lib::*;
1522
1523    /// Inertial Navigation System update status message
1524    ///
1525    /// The INS update status message contains information about executed and
1526    /// rejected INS updates. This message is expected to be extended in the
1527    /// future as new types of measurements are being added.
1528    ///
1529    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1530    #[allow(clippy::derive_partial_eq_without_eq)]
1531    #[derive(Debug, PartialEq, Clone)]
1532    pub struct MsgInsUpdates {
1533        /// The message sender_id
1534        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1535        pub sender_id: Option<u16>,
1536        /// GPS Time of Week
1537        #[cfg_attr(feature = "serde", serde(rename = "tow"))]
1538        pub tow: u32,
1539        /// GNSS position update status flags
1540        #[cfg_attr(feature = "serde", serde(rename = "gnsspos"))]
1541        pub gnsspos: u8,
1542        /// GNSS velocity update status flags
1543        #[cfg_attr(feature = "serde", serde(rename = "gnssvel"))]
1544        pub gnssvel: u8,
1545        /// Wheelticks update status flags
1546        #[cfg_attr(feature = "serde", serde(rename = "wheelticks"))]
1547        pub wheelticks: u8,
1548        /// Wheelticks update status flags
1549        #[cfg_attr(feature = "serde", serde(rename = "speed"))]
1550        pub speed: u8,
1551        /// NHC update status flags
1552        #[cfg_attr(feature = "serde", serde(rename = "nhc"))]
1553        pub nhc: u8,
1554        /// Zero velocity update status flags
1555        #[cfg_attr(feature = "serde", serde(rename = "zerovel"))]
1556        pub zerovel: u8,
1557    }
1558
1559    impl MsgInsUpdates {
1560        /// Gets the `number_of_attempted_gnss_position_updates_since_last_message` stored in `gnsspos`.
1561        pub fn number_of_attempted_gnss_position_updates_since_last_message(&self) -> u8 {
1562            get_bit_range!(self.gnsspos, u8, u8, 7, 4)
1563        }
1564
1565        /// Sets the `number_of_attempted_gnss_position_updates_since_last_message` bitrange of `gnsspos`.
1566        pub fn set_number_of_attempted_gnss_position_updates_since_last_message(
1567            &mut self,
1568            number_of_attempted_gnss_position_updates_since_last_message: u8,
1569        ) {
1570            set_bit_range!(
1571                &mut self.gnsspos,
1572                number_of_attempted_gnss_position_updates_since_last_message,
1573                u8,
1574                u8,
1575                7,
1576                4
1577            );
1578        }
1579
1580        /// Gets the `number_of_rejected_gnss_position_updates_since_last_message` stored in `gnsspos`.
1581        pub fn number_of_rejected_gnss_position_updates_since_last_message(&self) -> u8 {
1582            get_bit_range!(self.gnsspos, u8, u8, 3, 0)
1583        }
1584
1585        /// Sets the `number_of_rejected_gnss_position_updates_since_last_message` bitrange of `gnsspos`.
1586        pub fn set_number_of_rejected_gnss_position_updates_since_last_message(
1587            &mut self,
1588            number_of_rejected_gnss_position_updates_since_last_message: u8,
1589        ) {
1590            set_bit_range!(
1591                &mut self.gnsspos,
1592                number_of_rejected_gnss_position_updates_since_last_message,
1593                u8,
1594                u8,
1595                3,
1596                0
1597            );
1598        }
1599
1600        /// Gets the `number_of_attempted_gnss_velocity_updates_since_last_message` stored in `gnssvel`.
1601        pub fn number_of_attempted_gnss_velocity_updates_since_last_message(&self) -> u8 {
1602            get_bit_range!(self.gnssvel, u8, u8, 7, 4)
1603        }
1604
1605        /// Sets the `number_of_attempted_gnss_velocity_updates_since_last_message` bitrange of `gnssvel`.
1606        pub fn set_number_of_attempted_gnss_velocity_updates_since_last_message(
1607            &mut self,
1608            number_of_attempted_gnss_velocity_updates_since_last_message: u8,
1609        ) {
1610            set_bit_range!(
1611                &mut self.gnssvel,
1612                number_of_attempted_gnss_velocity_updates_since_last_message,
1613                u8,
1614                u8,
1615                7,
1616                4
1617            );
1618        }
1619
1620        /// Gets the `number_of_rejected_gnss_velocity_updates_since_last_message` stored in `gnssvel`.
1621        pub fn number_of_rejected_gnss_velocity_updates_since_last_message(&self) -> u8 {
1622            get_bit_range!(self.gnssvel, u8, u8, 3, 0)
1623        }
1624
1625        /// Sets the `number_of_rejected_gnss_velocity_updates_since_last_message` bitrange of `gnssvel`.
1626        pub fn set_number_of_rejected_gnss_velocity_updates_since_last_message(
1627            &mut self,
1628            number_of_rejected_gnss_velocity_updates_since_last_message: u8,
1629        ) {
1630            set_bit_range!(
1631                &mut self.gnssvel,
1632                number_of_rejected_gnss_velocity_updates_since_last_message,
1633                u8,
1634                u8,
1635                3,
1636                0
1637            );
1638        }
1639
1640        /// Gets the `number_of_attempted_wheeltick_updates_since_last_message` stored in `wheelticks`.
1641        pub fn number_of_attempted_wheeltick_updates_since_last_message(&self) -> u8 {
1642            get_bit_range!(self.wheelticks, u8, u8, 7, 4)
1643        }
1644
1645        /// Sets the `number_of_attempted_wheeltick_updates_since_last_message` bitrange of `wheelticks`.
1646        pub fn set_number_of_attempted_wheeltick_updates_since_last_message(
1647            &mut self,
1648            number_of_attempted_wheeltick_updates_since_last_message: u8,
1649        ) {
1650            set_bit_range!(
1651                &mut self.wheelticks,
1652                number_of_attempted_wheeltick_updates_since_last_message,
1653                u8,
1654                u8,
1655                7,
1656                4
1657            );
1658        }
1659
1660        /// Gets the `number_of_rejected_wheeltick_updates_since_last_message` stored in `wheelticks`.
1661        pub fn number_of_rejected_wheeltick_updates_since_last_message(&self) -> u8 {
1662            get_bit_range!(self.wheelticks, u8, u8, 3, 0)
1663        }
1664
1665        /// Sets the `number_of_rejected_wheeltick_updates_since_last_message` bitrange of `wheelticks`.
1666        pub fn set_number_of_rejected_wheeltick_updates_since_last_message(
1667            &mut self,
1668            number_of_rejected_wheeltick_updates_since_last_message: u8,
1669        ) {
1670            set_bit_range!(
1671                &mut self.wheelticks,
1672                number_of_rejected_wheeltick_updates_since_last_message,
1673                u8,
1674                u8,
1675                3,
1676                0
1677            );
1678        }
1679
1680        /// Gets the `number_of_attempted_speed_updates_since_last_message` stored in `speed`.
1681        pub fn number_of_attempted_speed_updates_since_last_message(&self) -> u8 {
1682            get_bit_range!(self.speed, u8, u8, 7, 4)
1683        }
1684
1685        /// Sets the `number_of_attempted_speed_updates_since_last_message` bitrange of `speed`.
1686        pub fn set_number_of_attempted_speed_updates_since_last_message(
1687            &mut self,
1688            number_of_attempted_speed_updates_since_last_message: u8,
1689        ) {
1690            set_bit_range!(
1691                &mut self.speed,
1692                number_of_attempted_speed_updates_since_last_message,
1693                u8,
1694                u8,
1695                7,
1696                4
1697            );
1698        }
1699
1700        /// Gets the `number_of_rejected_speed_updates_since_last_message` stored in `speed`.
1701        pub fn number_of_rejected_speed_updates_since_last_message(&self) -> u8 {
1702            get_bit_range!(self.speed, u8, u8, 3, 0)
1703        }
1704
1705        /// Sets the `number_of_rejected_speed_updates_since_last_message` bitrange of `speed`.
1706        pub fn set_number_of_rejected_speed_updates_since_last_message(
1707            &mut self,
1708            number_of_rejected_speed_updates_since_last_message: u8,
1709        ) {
1710            set_bit_range!(
1711                &mut self.speed,
1712                number_of_rejected_speed_updates_since_last_message,
1713                u8,
1714                u8,
1715                3,
1716                0
1717            );
1718        }
1719
1720        /// Gets the `number_of_attempted_nhc_updates_since_last_message` stored in `nhc`.
1721        pub fn number_of_attempted_nhc_updates_since_last_message(&self) -> u8 {
1722            get_bit_range!(self.nhc, u8, u8, 7, 4)
1723        }
1724
1725        /// Sets the `number_of_attempted_nhc_updates_since_last_message` bitrange of `nhc`.
1726        pub fn set_number_of_attempted_nhc_updates_since_last_message(
1727            &mut self,
1728            number_of_attempted_nhc_updates_since_last_message: u8,
1729        ) {
1730            set_bit_range!(
1731                &mut self.nhc,
1732                number_of_attempted_nhc_updates_since_last_message,
1733                u8,
1734                u8,
1735                7,
1736                4
1737            );
1738        }
1739
1740        /// Gets the `number_of_rejected_nhc_updates_since_last_message` stored in `nhc`.
1741        pub fn number_of_rejected_nhc_updates_since_last_message(&self) -> u8 {
1742            get_bit_range!(self.nhc, u8, u8, 3, 0)
1743        }
1744
1745        /// Sets the `number_of_rejected_nhc_updates_since_last_message` bitrange of `nhc`.
1746        pub fn set_number_of_rejected_nhc_updates_since_last_message(
1747            &mut self,
1748            number_of_rejected_nhc_updates_since_last_message: u8,
1749        ) {
1750            set_bit_range!(
1751                &mut self.nhc,
1752                number_of_rejected_nhc_updates_since_last_message,
1753                u8,
1754                u8,
1755                3,
1756                0
1757            );
1758        }
1759
1760        /// Gets the `number_of_attempted_zero_velocity_updates_since_last_message` stored in `zerovel`.
1761        pub fn number_of_attempted_zero_velocity_updates_since_last_message(&self) -> u8 {
1762            get_bit_range!(self.zerovel, u8, u8, 7, 4)
1763        }
1764
1765        /// Sets the `number_of_attempted_zero_velocity_updates_since_last_message` bitrange of `zerovel`.
1766        pub fn set_number_of_attempted_zero_velocity_updates_since_last_message(
1767            &mut self,
1768            number_of_attempted_zero_velocity_updates_since_last_message: u8,
1769        ) {
1770            set_bit_range!(
1771                &mut self.zerovel,
1772                number_of_attempted_zero_velocity_updates_since_last_message,
1773                u8,
1774                u8,
1775                7,
1776                4
1777            );
1778        }
1779
1780        /// Gets the `number_of_rejected_zero_velocity_updates_since_last_message` stored in `zerovel`.
1781        pub fn number_of_rejected_zero_velocity_updates_since_last_message(&self) -> u8 {
1782            get_bit_range!(self.zerovel, u8, u8, 3, 0)
1783        }
1784
1785        /// Sets the `number_of_rejected_zero_velocity_updates_since_last_message` bitrange of `zerovel`.
1786        pub fn set_number_of_rejected_zero_velocity_updates_since_last_message(
1787            &mut self,
1788            number_of_rejected_zero_velocity_updates_since_last_message: u8,
1789        ) {
1790            set_bit_range!(
1791                &mut self.zerovel,
1792                number_of_rejected_zero_velocity_updates_since_last_message,
1793                u8,
1794                u8,
1795                3,
1796                0
1797            );
1798        }
1799    }
1800
1801    impl ConcreteMessage for MsgInsUpdates {
1802        const MESSAGE_TYPE: u16 = 65286;
1803        const MESSAGE_NAME: &'static str = "MSG_INS_UPDATES";
1804    }
1805
1806    impl SbpMessage for MsgInsUpdates {
1807        fn message_name(&self) -> &'static str {
1808            <Self as ConcreteMessage>::MESSAGE_NAME
1809        }
1810        fn message_type(&self) -> Option<u16> {
1811            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1812        }
1813        fn sender_id(&self) -> Option<u16> {
1814            self.sender_id
1815        }
1816        fn set_sender_id(&mut self, new_id: u16) {
1817            self.sender_id = Some(new_id);
1818        }
1819        fn encoded_len(&self) -> usize {
1820            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1821        }
1822        fn is_valid(&self) -> bool {
1823            true
1824        }
1825        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1826            Ok(self)
1827        }
1828
1829        #[cfg(feature = "swiftnav")]
1830        fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1831            let tow_s = (self.tow as f64) / 1000.0;
1832            let gps_time = match time::GpsTime::new(0, tow_s) {
1833                Ok(gps_time) => gps_time.tow(),
1834                Err(e) => return Some(Err(e.into())),
1835            };
1836            Some(Ok(time::MessageTime::Rover(gps_time.into())))
1837        }
1838    }
1839
1840    impl FriendlyName for MsgInsUpdates {
1841        fn friendly_name() -> &'static str {
1842            "INS UPDATES"
1843        }
1844    }
1845
1846    impl TryFrom<Sbp> for MsgInsUpdates {
1847        type Error = TryFromSbpError;
1848        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1849            match msg {
1850                Sbp::MsgInsUpdates(m) => Ok(m),
1851                _ => Err(TryFromSbpError(msg)),
1852            }
1853        }
1854    }
1855
1856    impl WireFormat for MsgInsUpdates {
1857        const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
1858            + <u8 as WireFormat>::MIN_LEN
1859            + <u8 as WireFormat>::MIN_LEN
1860            + <u8 as WireFormat>::MIN_LEN
1861            + <u8 as WireFormat>::MIN_LEN
1862            + <u8 as WireFormat>::MIN_LEN
1863            + <u8 as WireFormat>::MIN_LEN;
1864        fn len(&self) -> usize {
1865            WireFormat::len(&self.tow)
1866                + WireFormat::len(&self.gnsspos)
1867                + WireFormat::len(&self.gnssvel)
1868                + WireFormat::len(&self.wheelticks)
1869                + WireFormat::len(&self.speed)
1870                + WireFormat::len(&self.nhc)
1871                + WireFormat::len(&self.zerovel)
1872        }
1873        fn write<B: BufMut>(&self, buf: &mut B) {
1874            WireFormat::write(&self.tow, buf);
1875            WireFormat::write(&self.gnsspos, buf);
1876            WireFormat::write(&self.gnssvel, buf);
1877            WireFormat::write(&self.wheelticks, buf);
1878            WireFormat::write(&self.speed, buf);
1879            WireFormat::write(&self.nhc, buf);
1880            WireFormat::write(&self.zerovel, buf);
1881        }
1882        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1883            MsgInsUpdates {
1884                sender_id: None,
1885                tow: WireFormat::parse_unchecked(buf),
1886                gnsspos: WireFormat::parse_unchecked(buf),
1887                gnssvel: WireFormat::parse_unchecked(buf),
1888                wheelticks: WireFormat::parse_unchecked(buf),
1889                speed: WireFormat::parse_unchecked(buf),
1890                nhc: WireFormat::parse_unchecked(buf),
1891                zerovel: WireFormat::parse_unchecked(buf),
1892            }
1893        }
1894    }
1895}
1896
1897pub mod msg_pps_time {
1898    #![allow(unused_imports)]
1899
1900    use super::*;
1901    use crate::messages::lib::*;
1902
1903    /// Local time at detection of PPS pulse
1904    ///
1905    /// The PPS time message contains the value of the sender's local time in
1906    /// microseconds at the moment a pulse is detected on the PPS input. This is
1907    /// to be used for synchronisation of sensor data sampled with a local
1908    /// timestamp (e.g. IMU or wheeltick messages) where GNSS time is unknown to
1909    /// the sender.
1910    ///
1911    /// The local time used to timestamp the PPS pulse must be generated by the
1912    /// same clock which is used to timestamp the IMU/wheel sensor data and should
1913    /// follow the same roll-over rules (i.e. it should roll over to zero after
1914    /// 604800 seconds). A separate MSG_PPS_TIME message should be sent for each
1915    /// source of sensor data which uses local timestamping.  The sender ID for
1916    /// each of these MSG_PPS_TIME messages should match the sender ID of the
1917    /// respective sensor data.
1918    ///
1919    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1920    #[allow(clippy::derive_partial_eq_without_eq)]
1921    #[derive(Debug, PartialEq, Clone)]
1922    pub struct MsgPpsTime {
1923        /// The message sender_id
1924        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1925        pub sender_id: Option<u16>,
1926        /// Local time in microseconds
1927        #[cfg_attr(feature = "serde", serde(rename = "time"))]
1928        pub time: u64,
1929        /// Status flags
1930        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1931        pub flags: u8,
1932    }
1933
1934    impl MsgPpsTime {
1935        /// Gets the `reserved_set_to_zero` stored in `flags`.
1936        pub fn reserved_set_to_zero(&self) -> u8 {
1937            get_bit_range!(self.flags, u8, u8, 7, 2)
1938        }
1939
1940        /// Sets the `reserved_set_to_zero` bitrange of `flags`.
1941        pub fn set_reserved_set_to_zero(&mut self, reserved_set_to_zero: u8) {
1942            set_bit_range!(&mut self.flags, reserved_set_to_zero, u8, u8, 7, 2);
1943        }
1944
1945        /// Gets the [TimeUncertainty][self::TimeUncertainty] stored in the `flags` bitfield.
1946        ///
1947        /// Returns `Ok` if the bitrange contains a known `TimeUncertainty` variant.
1948        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
1949        /// or because new variants of `TimeUncertainty` were added.
1950        pub fn time_uncertainty(&self) -> Result<TimeUncertainty, u8> {
1951            get_bit_range!(self.flags, u8, u8, 1, 0).try_into()
1952        }
1953
1954        /// Set the bitrange corresponding to the [TimeUncertainty][TimeUncertainty] of the `flags` bitfield.
1955        pub fn set_time_uncertainty(&mut self, time_uncertainty: TimeUncertainty) {
1956            set_bit_range!(&mut self.flags, time_uncertainty, u8, u8, 1, 0);
1957        }
1958    }
1959
1960    impl ConcreteMessage for MsgPpsTime {
1961        const MESSAGE_TYPE: u16 = 65288;
1962        const MESSAGE_NAME: &'static str = "MSG_PPS_TIME";
1963    }
1964
1965    impl SbpMessage for MsgPpsTime {
1966        fn message_name(&self) -> &'static str {
1967            <Self as ConcreteMessage>::MESSAGE_NAME
1968        }
1969        fn message_type(&self) -> Option<u16> {
1970            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1971        }
1972        fn sender_id(&self) -> Option<u16> {
1973            self.sender_id
1974        }
1975        fn set_sender_id(&mut self, new_id: u16) {
1976            self.sender_id = Some(new_id);
1977        }
1978        fn encoded_len(&self) -> usize {
1979            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1980        }
1981        fn is_valid(&self) -> bool {
1982            true
1983        }
1984        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1985            Ok(self)
1986        }
1987    }
1988
1989    impl FriendlyName for MsgPpsTime {
1990        fn friendly_name() -> &'static str {
1991            "PPS TIME"
1992        }
1993    }
1994
1995    impl TryFrom<Sbp> for MsgPpsTime {
1996        type Error = TryFromSbpError;
1997        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1998            match msg {
1999                Sbp::MsgPpsTime(m) => Ok(m),
2000                _ => Err(TryFromSbpError(msg)),
2001            }
2002        }
2003    }
2004
2005    impl WireFormat for MsgPpsTime {
2006        const MIN_LEN: usize = <u64 as WireFormat>::MIN_LEN + <u8 as WireFormat>::MIN_LEN;
2007        fn len(&self) -> usize {
2008            WireFormat::len(&self.time) + WireFormat::len(&self.flags)
2009        }
2010        fn write<B: BufMut>(&self, buf: &mut B) {
2011            WireFormat::write(&self.time, buf);
2012            WireFormat::write(&self.flags, buf);
2013        }
2014        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2015            MsgPpsTime {
2016                sender_id: None,
2017                time: WireFormat::parse_unchecked(buf),
2018                flags: WireFormat::parse_unchecked(buf),
2019            }
2020        }
2021    }
2022
2023    /// Time uncertainty
2024    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2025    pub enum TimeUncertainty {
2026        /// Unknown
2027        Unknown = 0,
2028
2029        /// +/- 10 milliseconds
2030        _10Milliseconds = 1,
2031
2032        /// +/- 10 microseconds
2033        _10Microseconds = 2,
2034
2035        /// < 1 microseconds
2036        _1Microseconds = 3,
2037    }
2038
2039    impl std::fmt::Display for TimeUncertainty {
2040        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2041            match self {
2042                TimeUncertainty::Unknown => f.write_str("Unknown"),
2043                TimeUncertainty::_10Milliseconds => f.write_str("+/- 10 milliseconds"),
2044                TimeUncertainty::_10Microseconds => f.write_str("+/- 10 microseconds"),
2045                TimeUncertainty::_1Microseconds => f.write_str("< 1 microseconds"),
2046            }
2047        }
2048    }
2049
2050    impl TryFrom<u8> for TimeUncertainty {
2051        type Error = u8;
2052        fn try_from(i: u8) -> Result<Self, u8> {
2053            match i {
2054                0 => Ok(TimeUncertainty::Unknown),
2055                1 => Ok(TimeUncertainty::_10Milliseconds),
2056                2 => Ok(TimeUncertainty::_10Microseconds),
2057                3 => Ok(TimeUncertainty::_1Microseconds),
2058                i => Err(i),
2059            }
2060        }
2061    }
2062}
2063
2064pub mod msg_sensor_aid_event {
2065    #![allow(unused_imports)]
2066
2067    use super::*;
2068    use crate::messages::lib::*;
2069
2070    /// Sensor state and update status data
2071    ///
2072    /// This diagnostic message contains state and update status information for
2073    /// all sensors that are being used by the fusion engine. This message will be
2074    /// generated asynchronously to the solution messages and will be emitted
2075    /// anytime a sensor update is being processed.
2076    ///
2077    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2078    #[allow(clippy::derive_partial_eq_without_eq)]
2079    #[derive(Debug, PartialEq, Clone)]
2080    pub struct MsgSensorAidEvent {
2081        /// The message sender_id
2082        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2083        pub sender_id: Option<u16>,
2084        /// Update timestamp in milliseconds.
2085        #[cfg_attr(feature = "serde", serde(rename = "time"))]
2086        pub time: u32,
2087        /// Sensor type
2088        #[cfg_attr(feature = "serde", serde(rename = "sensor_type"))]
2089        pub sensor_type: u8,
2090        /// Sensor identifier
2091        #[cfg_attr(feature = "serde", serde(rename = "sensor_id"))]
2092        pub sensor_id: u16,
2093        /// Reserved for future use
2094        #[cfg_attr(feature = "serde", serde(rename = "sensor_state"))]
2095        pub sensor_state: u8,
2096        /// Number of available measurements in this epoch
2097        #[cfg_attr(feature = "serde", serde(rename = "n_available_meas"))]
2098        pub n_available_meas: u8,
2099        /// Number of attempted measurements in this epoch
2100        #[cfg_attr(feature = "serde", serde(rename = "n_attempted_meas"))]
2101        pub n_attempted_meas: u8,
2102        /// Number of accepted measurements in this epoch
2103        #[cfg_attr(feature = "serde", serde(rename = "n_accepted_meas"))]
2104        pub n_accepted_meas: u8,
2105        /// Reserved for future use
2106        #[cfg_attr(feature = "serde", serde(rename = "flags"))]
2107        pub flags: u32,
2108    }
2109
2110    impl MsgSensorAidEvent {
2111        /// Gets the [TypeIdentifier][self::TypeIdentifier] stored in the `sensor_type` bitfield.
2112        ///
2113        /// Returns `Ok` if the bitrange contains a known `TypeIdentifier` variant.
2114        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
2115        /// or because new variants of `TypeIdentifier` were added.
2116        pub fn type_identifier(&self) -> Result<TypeIdentifier, u8> {
2117            get_bit_range!(self.sensor_type, u8, u8, 7, 0).try_into()
2118        }
2119
2120        /// Set the bitrange corresponding to the [TypeIdentifier][TypeIdentifier] of the `sensor_type` bitfield.
2121        pub fn set_type_identifier(&mut self, type_identifier: TypeIdentifier) {
2122            set_bit_range!(&mut self.sensor_type, type_identifier, u8, u8, 7, 0);
2123        }
2124    }
2125
2126    impl ConcreteMessage for MsgSensorAidEvent {
2127        const MESSAGE_TYPE: u16 = 65289;
2128        const MESSAGE_NAME: &'static str = "MSG_SENSOR_AID_EVENT";
2129    }
2130
2131    impl SbpMessage for MsgSensorAidEvent {
2132        fn message_name(&self) -> &'static str {
2133            <Self as ConcreteMessage>::MESSAGE_NAME
2134        }
2135        fn message_type(&self) -> Option<u16> {
2136            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2137        }
2138        fn sender_id(&self) -> Option<u16> {
2139            self.sender_id
2140        }
2141        fn set_sender_id(&mut self, new_id: u16) {
2142            self.sender_id = Some(new_id);
2143        }
2144        fn encoded_len(&self) -> usize {
2145            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2146        }
2147        fn is_valid(&self) -> bool {
2148            true
2149        }
2150        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2151            Ok(self)
2152        }
2153    }
2154
2155    impl FriendlyName for MsgSensorAidEvent {
2156        fn friendly_name() -> &'static str {
2157            "SENSOR AID EVENT"
2158        }
2159    }
2160
2161    impl TryFrom<Sbp> for MsgSensorAidEvent {
2162        type Error = TryFromSbpError;
2163        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2164            match msg {
2165                Sbp::MsgSensorAidEvent(m) => Ok(m),
2166                _ => Err(TryFromSbpError(msg)),
2167            }
2168        }
2169    }
2170
2171    impl WireFormat for MsgSensorAidEvent {
2172        const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
2173            + <u8 as WireFormat>::MIN_LEN
2174            + <u16 as WireFormat>::MIN_LEN
2175            + <u8 as WireFormat>::MIN_LEN
2176            + <u8 as WireFormat>::MIN_LEN
2177            + <u8 as WireFormat>::MIN_LEN
2178            + <u8 as WireFormat>::MIN_LEN
2179            + <u32 as WireFormat>::MIN_LEN;
2180        fn len(&self) -> usize {
2181            WireFormat::len(&self.time)
2182                + WireFormat::len(&self.sensor_type)
2183                + WireFormat::len(&self.sensor_id)
2184                + WireFormat::len(&self.sensor_state)
2185                + WireFormat::len(&self.n_available_meas)
2186                + WireFormat::len(&self.n_attempted_meas)
2187                + WireFormat::len(&self.n_accepted_meas)
2188                + WireFormat::len(&self.flags)
2189        }
2190        fn write<B: BufMut>(&self, buf: &mut B) {
2191            WireFormat::write(&self.time, buf);
2192            WireFormat::write(&self.sensor_type, buf);
2193            WireFormat::write(&self.sensor_id, buf);
2194            WireFormat::write(&self.sensor_state, buf);
2195            WireFormat::write(&self.n_available_meas, buf);
2196            WireFormat::write(&self.n_attempted_meas, buf);
2197            WireFormat::write(&self.n_accepted_meas, buf);
2198            WireFormat::write(&self.flags, buf);
2199        }
2200        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2201            MsgSensorAidEvent {
2202                sender_id: None,
2203                time: WireFormat::parse_unchecked(buf),
2204                sensor_type: WireFormat::parse_unchecked(buf),
2205                sensor_id: WireFormat::parse_unchecked(buf),
2206                sensor_state: WireFormat::parse_unchecked(buf),
2207                n_available_meas: WireFormat::parse_unchecked(buf),
2208                n_attempted_meas: WireFormat::parse_unchecked(buf),
2209                n_accepted_meas: WireFormat::parse_unchecked(buf),
2210                flags: WireFormat::parse_unchecked(buf),
2211            }
2212        }
2213    }
2214
2215    /// Type identifier
2216    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2217    pub enum TypeIdentifier {
2218        /// GNSS position
2219        GnssPosition = 0,
2220
2221        /// GNSS average velocity
2222        GnssAverageVelocity = 1,
2223
2224        /// GNSS instantaneous velocity
2225        GnssInstantaneousVelocity = 2,
2226
2227        /// Wheel ticks
2228        WheelTicks = 3,
2229
2230        /// Wheel speed
2231        WheelSpeed = 4,
2232
2233        /// IMU
2234        Imu = 5,
2235
2236        /// Time differences of carrier phase
2237        TimeDifferencesOfCarrierPhase = 6,
2238    }
2239
2240    impl std::fmt::Display for TypeIdentifier {
2241        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2242            match self {
2243                TypeIdentifier::GnssPosition => f.write_str("GNSS position"),
2244                TypeIdentifier::GnssAverageVelocity => f.write_str("GNSS average velocity"),
2245                TypeIdentifier::GnssInstantaneousVelocity => {
2246                    f.write_str("GNSS instantaneous velocity")
2247                }
2248                TypeIdentifier::WheelTicks => f.write_str("Wheel ticks"),
2249                TypeIdentifier::WheelSpeed => f.write_str("Wheel speed"),
2250                TypeIdentifier::Imu => f.write_str("IMU"),
2251                TypeIdentifier::TimeDifferencesOfCarrierPhase => {
2252                    f.write_str("Time differences of carrier phase")
2253                }
2254            }
2255        }
2256    }
2257
2258    impl TryFrom<u8> for TypeIdentifier {
2259        type Error = u8;
2260        fn try_from(i: u8) -> Result<Self, u8> {
2261            match i {
2262                0 => Ok(TypeIdentifier::GnssPosition),
2263                1 => Ok(TypeIdentifier::GnssAverageVelocity),
2264                2 => Ok(TypeIdentifier::GnssInstantaneousVelocity),
2265                3 => Ok(TypeIdentifier::WheelTicks),
2266                4 => Ok(TypeIdentifier::WheelSpeed),
2267                5 => Ok(TypeIdentifier::Imu),
2268                6 => Ok(TypeIdentifier::TimeDifferencesOfCarrierPhase),
2269                i => Err(i),
2270            }
2271        }
2272    }
2273}
2274
2275pub mod msg_startup {
2276    #![allow(unused_imports)]
2277
2278    use super::*;
2279    use crate::messages::lib::*;
2280
2281    /// System start-up message
2282    ///
2283    /// The system start-up message is sent once on system start-up. It notifies
2284    /// the host or other attached devices that the system has started and is now
2285    /// ready to respond to commands or configuration requests.
2286    ///
2287    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2288    #[allow(clippy::derive_partial_eq_without_eq)]
2289    #[derive(Debug, PartialEq, Clone)]
2290    pub struct MsgStartup {
2291        /// The message sender_id
2292        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2293        pub sender_id: Option<u16>,
2294        /// Cause of startup
2295        #[cfg_attr(feature = "serde", serde(rename = "cause"))]
2296        pub cause: u8,
2297        /// Startup type
2298        #[cfg_attr(feature = "serde", serde(rename = "startup_type"))]
2299        pub startup_type: u8,
2300        /// Reserved
2301        #[cfg_attr(feature = "serde", serde(rename = "reserved"))]
2302        pub reserved: u16,
2303    }
2304
2305    impl MsgStartup {
2306        /// Gets the [CauseOfStartup][self::CauseOfStartup] stored in the `cause` bitfield.
2307        ///
2308        /// Returns `Ok` if the bitrange contains a known `CauseOfStartup` variant.
2309        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
2310        /// or because new variants of `CauseOfStartup` were added.
2311        pub fn cause_of_startup(&self) -> Result<CauseOfStartup, u8> {
2312            get_bit_range!(self.cause, u8, u8, 7, 0).try_into()
2313        }
2314
2315        /// Set the bitrange corresponding to the [CauseOfStartup][CauseOfStartup] of the `cause` bitfield.
2316        pub fn set_cause_of_startup(&mut self, cause_of_startup: CauseOfStartup) {
2317            set_bit_range!(&mut self.cause, cause_of_startup, u8, u8, 7, 0);
2318        }
2319
2320        /// Gets the [StartupType][self::StartupType] stored in the `startup_type` bitfield.
2321        ///
2322        /// Returns `Ok` if the bitrange contains a known `StartupType` variant.
2323        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
2324        /// or because new variants of `StartupType` were added.
2325        pub fn startup_type(&self) -> Result<StartupType, u8> {
2326            get_bit_range!(self.startup_type, u8, u8, 7, 0).try_into()
2327        }
2328
2329        /// Set the bitrange corresponding to the [StartupType][StartupType] of the `startup_type` bitfield.
2330        pub fn set_startup_type(&mut self, startup_type: StartupType) {
2331            set_bit_range!(&mut self.startup_type, startup_type, u8, u8, 7, 0);
2332        }
2333    }
2334
2335    impl ConcreteMessage for MsgStartup {
2336        const MESSAGE_TYPE: u16 = 65280;
2337        const MESSAGE_NAME: &'static str = "MSG_STARTUP";
2338    }
2339
2340    impl SbpMessage for MsgStartup {
2341        fn message_name(&self) -> &'static str {
2342            <Self as ConcreteMessage>::MESSAGE_NAME
2343        }
2344        fn message_type(&self) -> Option<u16> {
2345            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2346        }
2347        fn sender_id(&self) -> Option<u16> {
2348            self.sender_id
2349        }
2350        fn set_sender_id(&mut self, new_id: u16) {
2351            self.sender_id = Some(new_id);
2352        }
2353        fn encoded_len(&self) -> usize {
2354            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2355        }
2356        fn is_valid(&self) -> bool {
2357            true
2358        }
2359        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2360            Ok(self)
2361        }
2362    }
2363
2364    impl FriendlyName for MsgStartup {
2365        fn friendly_name() -> &'static str {
2366            "STARTUP"
2367        }
2368    }
2369
2370    impl TryFrom<Sbp> for MsgStartup {
2371        type Error = TryFromSbpError;
2372        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2373            match msg {
2374                Sbp::MsgStartup(m) => Ok(m),
2375                _ => Err(TryFromSbpError(msg)),
2376            }
2377        }
2378    }
2379
2380    impl WireFormat for MsgStartup {
2381        const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
2382            + <u8 as WireFormat>::MIN_LEN
2383            + <u16 as WireFormat>::MIN_LEN;
2384        fn len(&self) -> usize {
2385            WireFormat::len(&self.cause)
2386                + WireFormat::len(&self.startup_type)
2387                + WireFormat::len(&self.reserved)
2388        }
2389        fn write<B: BufMut>(&self, buf: &mut B) {
2390            WireFormat::write(&self.cause, buf);
2391            WireFormat::write(&self.startup_type, buf);
2392            WireFormat::write(&self.reserved, buf);
2393        }
2394        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2395            MsgStartup {
2396                sender_id: None,
2397                cause: WireFormat::parse_unchecked(buf),
2398                startup_type: WireFormat::parse_unchecked(buf),
2399                reserved: WireFormat::parse_unchecked(buf),
2400            }
2401        }
2402    }
2403
2404    /// Cause of startup
2405    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2406    pub enum CauseOfStartup {
2407        /// Power on
2408        PowerOn = 0,
2409
2410        /// Software reset
2411        SoftwareReset = 1,
2412
2413        /// Watchdog reset
2414        WatchdogReset = 2,
2415    }
2416
2417    impl std::fmt::Display for CauseOfStartup {
2418        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2419            match self {
2420                CauseOfStartup::PowerOn => f.write_str("Power on"),
2421                CauseOfStartup::SoftwareReset => f.write_str("Software reset"),
2422                CauseOfStartup::WatchdogReset => f.write_str("Watchdog reset"),
2423            }
2424        }
2425    }
2426
2427    impl TryFrom<u8> for CauseOfStartup {
2428        type Error = u8;
2429        fn try_from(i: u8) -> Result<Self, u8> {
2430            match i {
2431                0 => Ok(CauseOfStartup::PowerOn),
2432                1 => Ok(CauseOfStartup::SoftwareReset),
2433                2 => Ok(CauseOfStartup::WatchdogReset),
2434                i => Err(i),
2435            }
2436        }
2437    }
2438
2439    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2440    pub enum StartupType {
2441        /// Cold start
2442        ColdStart = 0,
2443
2444        /// Warm start
2445        WarmStart = 1,
2446
2447        /// Hot start
2448        HotStart = 2,
2449    }
2450
2451    impl std::fmt::Display for StartupType {
2452        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2453            match self {
2454                StartupType::ColdStart => f.write_str("Cold start"),
2455                StartupType::WarmStart => f.write_str("Warm start"),
2456                StartupType::HotStart => f.write_str("Hot start"),
2457            }
2458        }
2459    }
2460
2461    impl TryFrom<u8> for StartupType {
2462        type Error = u8;
2463        fn try_from(i: u8) -> Result<Self, u8> {
2464            match i {
2465                0 => Ok(StartupType::ColdStart),
2466                1 => Ok(StartupType::WarmStart),
2467                2 => Ok(StartupType::HotStart),
2468                i => Err(i),
2469            }
2470        }
2471    }
2472}
2473
2474pub mod msg_status_journal {
2475    #![allow(unused_imports)]
2476
2477    use super::*;
2478    use crate::messages::lib::*;
2479
2480    /// Status report journal
2481    ///
2482    /// The status journal message contains past status reports (see
2483    /// MSG_STATUS_REPORT) and functions as a error/event storage for telemetry
2484    /// purposes.
2485    ///
2486    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2487    #[allow(clippy::derive_partial_eq_without_eq)]
2488    #[derive(Debug, PartialEq, Clone)]
2489    pub struct MsgStatusJournal {
2490        /// The message sender_id
2491        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2492        pub sender_id: Option<u16>,
2493        /// Identity of reporting system
2494        #[cfg_attr(feature = "serde", serde(rename = "reporting_system"))]
2495        pub reporting_system: u16,
2496        /// SBP protocol version
2497        #[cfg_attr(feature = "serde", serde(rename = "sbp_version"))]
2498        pub sbp_version: u16,
2499        /// Total number of status reports sent since system startup
2500        #[cfg_attr(feature = "serde", serde(rename = "total_status_reports"))]
2501        pub total_status_reports: u32,
2502        /// Index and number of messages in this sequence. First nibble is the size
2503        /// of the sequence (n), second nibble is the zero-indexed counter (ith
2504        /// packet of n)
2505        #[cfg_attr(feature = "serde", serde(rename = "sequence_descriptor"))]
2506        pub sequence_descriptor: u8,
2507        /// Status journal
2508        #[cfg_attr(feature = "serde", serde(rename = "journal"))]
2509        pub journal: Vec<StatusJournalItem>,
2510    }
2511
2512    impl MsgStatusJournal {
2513        /// Gets the [System][self::System] stored in the `reporting_system` bitfield.
2514        ///
2515        /// Returns `Ok` if the bitrange contains a known `System` variant.
2516        /// Otherwise the value of the bitrange is returned as an `Err(u16)`. This may be because of a malformed message,
2517        /// or because new variants of `System` were added.
2518        pub fn system(&self) -> Result<System, u16> {
2519            get_bit_range!(self.reporting_system, u16, u16, 15, 0).try_into()
2520        }
2521
2522        /// Set the bitrange corresponding to the [System][System] of the `reporting_system` bitfield.
2523        pub fn set_system(&mut self, system: System) {
2524            set_bit_range!(&mut self.reporting_system, system, u16, u16, 15, 0);
2525        }
2526
2527        /// Gets the `sbp_major_protocol_version_number` stored in `sbp_version`.
2528        pub fn sbp_major_protocol_version_number(&self) -> u8 {
2529            get_bit_range!(self.sbp_version, u16, u8, 15, 8)
2530        }
2531
2532        /// Sets the `sbp_major_protocol_version_number` bitrange of `sbp_version`.
2533        pub fn set_sbp_major_protocol_version_number(
2534            &mut self,
2535            sbp_major_protocol_version_number: u8,
2536        ) {
2537            set_bit_range!(
2538                &mut self.sbp_version,
2539                sbp_major_protocol_version_number,
2540                u16,
2541                u8,
2542                15,
2543                8
2544            );
2545        }
2546
2547        /// Gets the `sbp_minor_protocol_version_number` stored in `sbp_version`.
2548        pub fn sbp_minor_protocol_version_number(&self) -> u8 {
2549            get_bit_range!(self.sbp_version, u16, u8, 7, 0)
2550        }
2551
2552        /// Sets the `sbp_minor_protocol_version_number` bitrange of `sbp_version`.
2553        pub fn set_sbp_minor_protocol_version_number(
2554            &mut self,
2555            sbp_minor_protocol_version_number: u8,
2556        ) {
2557            set_bit_range!(
2558                &mut self.sbp_version,
2559                sbp_minor_protocol_version_number,
2560                u16,
2561                u8,
2562                7,
2563                0
2564            );
2565        }
2566    }
2567
2568    impl ConcreteMessage for MsgStatusJournal {
2569        const MESSAGE_TYPE: u16 = 65533;
2570        const MESSAGE_NAME: &'static str = "MSG_STATUS_JOURNAL";
2571    }
2572
2573    impl SbpMessage for MsgStatusJournal {
2574        fn message_name(&self) -> &'static str {
2575            <Self as ConcreteMessage>::MESSAGE_NAME
2576        }
2577        fn message_type(&self) -> Option<u16> {
2578            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2579        }
2580        fn sender_id(&self) -> Option<u16> {
2581            self.sender_id
2582        }
2583        fn set_sender_id(&mut self, new_id: u16) {
2584            self.sender_id = Some(new_id);
2585        }
2586        fn encoded_len(&self) -> usize {
2587            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2588        }
2589        fn is_valid(&self) -> bool {
2590            true
2591        }
2592        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2593            Ok(self)
2594        }
2595    }
2596
2597    impl FriendlyName for MsgStatusJournal {
2598        fn friendly_name() -> &'static str {
2599            "STATUS JOURNAL"
2600        }
2601    }
2602
2603    impl TryFrom<Sbp> for MsgStatusJournal {
2604        type Error = TryFromSbpError;
2605        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2606            match msg {
2607                Sbp::MsgStatusJournal(m) => Ok(m),
2608                _ => Err(TryFromSbpError(msg)),
2609            }
2610        }
2611    }
2612
2613    impl WireFormat for MsgStatusJournal {
2614        const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
2615            + <u16 as WireFormat>::MIN_LEN
2616            + <u32 as WireFormat>::MIN_LEN
2617            + <u8 as WireFormat>::MIN_LEN
2618            + <Vec<StatusJournalItem> as WireFormat>::MIN_LEN;
2619        fn len(&self) -> usize {
2620            WireFormat::len(&self.reporting_system)
2621                + WireFormat::len(&self.sbp_version)
2622                + WireFormat::len(&self.total_status_reports)
2623                + WireFormat::len(&self.sequence_descriptor)
2624                + WireFormat::len(&self.journal)
2625        }
2626        fn write<B: BufMut>(&self, buf: &mut B) {
2627            WireFormat::write(&self.reporting_system, buf);
2628            WireFormat::write(&self.sbp_version, buf);
2629            WireFormat::write(&self.total_status_reports, buf);
2630            WireFormat::write(&self.sequence_descriptor, buf);
2631            WireFormat::write(&self.journal, buf);
2632        }
2633        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2634            MsgStatusJournal {
2635                sender_id: None,
2636                reporting_system: WireFormat::parse_unchecked(buf),
2637                sbp_version: WireFormat::parse_unchecked(buf),
2638                total_status_reports: WireFormat::parse_unchecked(buf),
2639                sequence_descriptor: WireFormat::parse_unchecked(buf),
2640                journal: WireFormat::parse_unchecked(buf),
2641            }
2642        }
2643    }
2644
2645    /// System
2646    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2647    pub enum System {
2648        /// Starling
2649        Starling = 0,
2650
2651        /// Precision GNSS Module (PGM)
2652        PrecisionGnssModule = 1,
2653    }
2654
2655    impl std::fmt::Display for System {
2656        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2657            match self {
2658                System::Starling => f.write_str("Starling"),
2659                System::PrecisionGnssModule => f.write_str("Precision GNSS Module (PGM)"),
2660            }
2661        }
2662    }
2663
2664    impl TryFrom<u16> for System {
2665        type Error = u16;
2666        fn try_from(i: u16) -> Result<Self, u16> {
2667            match i {
2668                0 => Ok(System::Starling),
2669                1 => Ok(System::PrecisionGnssModule),
2670                i => Err(i),
2671            }
2672        }
2673    }
2674}
2675
2676pub mod msg_status_report {
2677    #![allow(unused_imports)]
2678
2679    use super::*;
2680    use crate::messages::lib::*;
2681
2682    /// Status report message
2683    ///
2684    /// The status report is sent periodically to inform the host or other
2685    /// attached devices that the system is running. It is used to monitor system
2686    /// malfunctions. It contains status reports that indicate to the host the
2687    /// status of each subsystem and whether it is operating correctly.
2688    ///
2689    /// Interpretation of the subsystem specific status code is product dependent,
2690    /// but if the generic status code is initializing, it should be ignored.
2691    /// Refer to product documentation for details.
2692    ///
2693    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2694    #[allow(clippy::derive_partial_eq_without_eq)]
2695    #[derive(Debug, PartialEq, Clone)]
2696    pub struct MsgStatusReport {
2697        /// The message sender_id
2698        #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2699        pub sender_id: Option<u16>,
2700        /// Identity of reporting system
2701        #[cfg_attr(feature = "serde", serde(rename = "reporting_system"))]
2702        pub reporting_system: u16,
2703        /// SBP protocol version
2704        #[cfg_attr(feature = "serde", serde(rename = "sbp_version"))]
2705        pub sbp_version: u16,
2706        /// Increments on each status report sent
2707        #[cfg_attr(feature = "serde", serde(rename = "sequence"))]
2708        pub sequence: u32,
2709        /// Number of seconds since system start-up
2710        #[cfg_attr(feature = "serde", serde(rename = "uptime"))]
2711        pub uptime: u32,
2712        /// Reported status of individual subsystems
2713        #[cfg_attr(feature = "serde", serde(rename = "status"))]
2714        pub status: Vec<SubSystemReport>,
2715    }
2716
2717    impl MsgStatusReport {
2718        /// Gets the [System][self::System] stored in the `reporting_system` bitfield.
2719        ///
2720        /// Returns `Ok` if the bitrange contains a known `System` variant.
2721        /// Otherwise the value of the bitrange is returned as an `Err(u16)`. This may be because of a malformed message,
2722        /// or because new variants of `System` were added.
2723        pub fn system(&self) -> Result<System, u16> {
2724            get_bit_range!(self.reporting_system, u16, u16, 15, 0).try_into()
2725        }
2726
2727        /// Set the bitrange corresponding to the [System][System] of the `reporting_system` bitfield.
2728        pub fn set_system(&mut self, system: System) {
2729            set_bit_range!(&mut self.reporting_system, system, u16, u16, 15, 0);
2730        }
2731
2732        /// Gets the `sbp_major_protocol_version_number` stored in `sbp_version`.
2733        pub fn sbp_major_protocol_version_number(&self) -> u8 {
2734            get_bit_range!(self.sbp_version, u16, u8, 15, 8)
2735        }
2736
2737        /// Sets the `sbp_major_protocol_version_number` bitrange of `sbp_version`.
2738        pub fn set_sbp_major_protocol_version_number(
2739            &mut self,
2740            sbp_major_protocol_version_number: u8,
2741        ) {
2742            set_bit_range!(
2743                &mut self.sbp_version,
2744                sbp_major_protocol_version_number,
2745                u16,
2746                u8,
2747                15,
2748                8
2749            );
2750        }
2751
2752        /// Gets the `sbp_minor_protocol_version_number` stored in `sbp_version`.
2753        pub fn sbp_minor_protocol_version_number(&self) -> u8 {
2754            get_bit_range!(self.sbp_version, u16, u8, 7, 0)
2755        }
2756
2757        /// Sets the `sbp_minor_protocol_version_number` bitrange of `sbp_version`.
2758        pub fn set_sbp_minor_protocol_version_number(
2759            &mut self,
2760            sbp_minor_protocol_version_number: u8,
2761        ) {
2762            set_bit_range!(
2763                &mut self.sbp_version,
2764                sbp_minor_protocol_version_number,
2765                u16,
2766                u8,
2767                7,
2768                0
2769            );
2770        }
2771    }
2772
2773    impl ConcreteMessage for MsgStatusReport {
2774        const MESSAGE_TYPE: u16 = 65534;
2775        const MESSAGE_NAME: &'static str = "MSG_STATUS_REPORT";
2776    }
2777
2778    impl SbpMessage for MsgStatusReport {
2779        fn message_name(&self) -> &'static str {
2780            <Self as ConcreteMessage>::MESSAGE_NAME
2781        }
2782        fn message_type(&self) -> Option<u16> {
2783            Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2784        }
2785        fn sender_id(&self) -> Option<u16> {
2786            self.sender_id
2787        }
2788        fn set_sender_id(&mut self, new_id: u16) {
2789            self.sender_id = Some(new_id);
2790        }
2791        fn encoded_len(&self) -> usize {
2792            WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2793        }
2794        fn is_valid(&self) -> bool {
2795            true
2796        }
2797        fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2798            Ok(self)
2799        }
2800    }
2801
2802    impl FriendlyName for MsgStatusReport {
2803        fn friendly_name() -> &'static str {
2804            "STATUS REPORT"
2805        }
2806    }
2807
2808    impl TryFrom<Sbp> for MsgStatusReport {
2809        type Error = TryFromSbpError;
2810        fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2811            match msg {
2812                Sbp::MsgStatusReport(m) => Ok(m),
2813                _ => Err(TryFromSbpError(msg)),
2814            }
2815        }
2816    }
2817
2818    impl WireFormat for MsgStatusReport {
2819        const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
2820            + <u16 as WireFormat>::MIN_LEN
2821            + <u32 as WireFormat>::MIN_LEN
2822            + <u32 as WireFormat>::MIN_LEN
2823            + <Vec<SubSystemReport> as WireFormat>::MIN_LEN;
2824        fn len(&self) -> usize {
2825            WireFormat::len(&self.reporting_system)
2826                + WireFormat::len(&self.sbp_version)
2827                + WireFormat::len(&self.sequence)
2828                + WireFormat::len(&self.uptime)
2829                + WireFormat::len(&self.status)
2830        }
2831        fn write<B: BufMut>(&self, buf: &mut B) {
2832            WireFormat::write(&self.reporting_system, buf);
2833            WireFormat::write(&self.sbp_version, buf);
2834            WireFormat::write(&self.sequence, buf);
2835            WireFormat::write(&self.uptime, buf);
2836            WireFormat::write(&self.status, buf);
2837        }
2838        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2839            MsgStatusReport {
2840                sender_id: None,
2841                reporting_system: WireFormat::parse_unchecked(buf),
2842                sbp_version: WireFormat::parse_unchecked(buf),
2843                sequence: WireFormat::parse_unchecked(buf),
2844                uptime: WireFormat::parse_unchecked(buf),
2845                status: WireFormat::parse_unchecked(buf),
2846            }
2847        }
2848    }
2849
2850    /// System
2851    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2852    pub enum System {
2853        /// Starling
2854        Starling = 0,
2855
2856        /// Precision GNSS Module (PGM)
2857        PrecisionGnssModule = 1,
2858    }
2859
2860    impl std::fmt::Display for System {
2861        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2862            match self {
2863                System::Starling => f.write_str("Starling"),
2864                System::PrecisionGnssModule => f.write_str("Precision GNSS Module (PGM)"),
2865            }
2866        }
2867    }
2868
2869    impl TryFrom<u16> for System {
2870        type Error = u16;
2871        fn try_from(i: u16) -> Result<Self, u16> {
2872            match i {
2873                0 => Ok(System::Starling),
2874                1 => Ok(System::PrecisionGnssModule),
2875                i => Err(i),
2876            }
2877        }
2878    }
2879}
2880
2881pub mod status_journal_item {
2882    #![allow(unused_imports)]
2883
2884    use super::*;
2885    use crate::messages::lib::*;
2886
2887    /// Subsystem Status report
2888    ///
2889    /// Reports the uptime and the state of a subsystem via generic and specific
2890    /// status codes.  If the generic state is reported as initializing, the
2891    /// specific state should be ignored.
2892    ///
2893    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2894    #[allow(clippy::derive_partial_eq_without_eq)]
2895    #[derive(Debug, PartialEq, Clone)]
2896    pub struct StatusJournalItem {
2897        /// Milliseconds since system startup
2898        #[cfg_attr(feature = "serde", serde(rename = "uptime"))]
2899        pub uptime: u32,
2900        #[cfg_attr(feature = "serde", serde(rename = "report"))]
2901        pub report: SubSystemReport,
2902    }
2903
2904    impl WireFormat for StatusJournalItem {
2905        const MIN_LEN: usize =
2906            <u32 as WireFormat>::MIN_LEN + <SubSystemReport as WireFormat>::MIN_LEN;
2907        fn len(&self) -> usize {
2908            WireFormat::len(&self.uptime) + WireFormat::len(&self.report)
2909        }
2910        fn write<B: BufMut>(&self, buf: &mut B) {
2911            WireFormat::write(&self.uptime, buf);
2912            WireFormat::write(&self.report, buf);
2913        }
2914        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2915            StatusJournalItem {
2916                uptime: WireFormat::parse_unchecked(buf),
2917                report: WireFormat::parse_unchecked(buf),
2918            }
2919        }
2920    }
2921}
2922
2923pub mod sub_system_report {
2924    #![allow(unused_imports)]
2925
2926    use super::*;
2927    use crate::messages::lib::*;
2928
2929    /// Subsystem Status report
2930    ///
2931    /// Report the general and specific state of a subsystem.  If the generic
2932    /// state is reported as initializing, the specific state should be ignored.
2933    ///
2934    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2935    #[allow(clippy::derive_partial_eq_without_eq)]
2936    #[derive(Debug, PartialEq, Clone)]
2937    pub struct SubSystemReport {
2938        /// Identity of reporting subsystem
2939        #[cfg_attr(feature = "serde", serde(rename = "component"))]
2940        pub component: u16,
2941        /// Generic form status report
2942        #[cfg_attr(feature = "serde", serde(rename = "generic"))]
2943        pub generic: u8,
2944        /// Subsystem specific status code
2945        #[cfg_attr(feature = "serde", serde(rename = "specific"))]
2946        pub specific: u8,
2947    }
2948
2949    impl SubSystemReport {
2950        /// Gets the [Subsystem][self::Subsystem] stored in the `component` bitfield.
2951        ///
2952        /// Returns `Ok` if the bitrange contains a known `Subsystem` variant.
2953        /// Otherwise the value of the bitrange is returned as an `Err(u16)`. This may be because of a malformed message,
2954        /// or because new variants of `Subsystem` were added.
2955        pub fn subsystem(&self) -> Result<Subsystem, u16> {
2956            get_bit_range!(self.component, u16, u16, 15, 0).try_into()
2957        }
2958
2959        /// Set the bitrange corresponding to the [Subsystem][Subsystem] of the `component` bitfield.
2960        pub fn set_subsystem(&mut self, subsystem: Subsystem) {
2961            set_bit_range!(&mut self.component, subsystem, u16, u16, 15, 0);
2962        }
2963
2964        /// Gets the [Generic][self::Generic] stored in the `generic` bitfield.
2965        ///
2966        /// Returns `Ok` if the bitrange contains a known `Generic` variant.
2967        /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message,
2968        /// or because new variants of `Generic` were added.
2969        pub fn generic(&self) -> Result<Generic, u8> {
2970            get_bit_range!(self.generic, u8, u8, 7, 0).try_into()
2971        }
2972
2973        /// Set the bitrange corresponding to the [Generic][Generic] of the `generic` bitfield.
2974        pub fn set_generic(&mut self, generic: Generic) {
2975            set_bit_range!(&mut self.generic, generic, u8, u8, 7, 0);
2976        }
2977    }
2978
2979    impl WireFormat for SubSystemReport {
2980        const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
2981            + <u8 as WireFormat>::MIN_LEN
2982            + <u8 as WireFormat>::MIN_LEN;
2983        fn len(&self) -> usize {
2984            WireFormat::len(&self.component)
2985                + WireFormat::len(&self.generic)
2986                + WireFormat::len(&self.specific)
2987        }
2988        fn write<B: BufMut>(&self, buf: &mut B) {
2989            WireFormat::write(&self.component, buf);
2990            WireFormat::write(&self.generic, buf);
2991            WireFormat::write(&self.specific, buf);
2992        }
2993        fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2994            SubSystemReport {
2995                component: WireFormat::parse_unchecked(buf),
2996                generic: WireFormat::parse_unchecked(buf),
2997                specific: WireFormat::parse_unchecked(buf),
2998            }
2999        }
3000    }
3001
3002    /// Subsystem
3003    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3004    pub enum Subsystem {
3005        /// Primary GNSS Antenna
3006        PrimaryGnssAntenna = 0,
3007
3008        /// Measurement Engine
3009        MeasurementEngine = 1,
3010
3011        /// Corrections Client
3012        CorrectionsClient = 2,
3013
3014        /// Differential GNSS Engine
3015        DifferentialGnssEngine = 3,
3016
3017        /// CAN
3018        Can = 4,
3019
3020        /// Wheel Odometry
3021        WheelOdometry = 5,
3022
3023        /// Sensor Fusion Engine
3024        SensorFusionEngine = 6,
3025    }
3026
3027    impl std::fmt::Display for Subsystem {
3028        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3029            match self {
3030                Subsystem::PrimaryGnssAntenna => f.write_str("Primary GNSS Antenna"),
3031                Subsystem::MeasurementEngine => f.write_str("Measurement Engine"),
3032                Subsystem::CorrectionsClient => f.write_str("Corrections Client"),
3033                Subsystem::DifferentialGnssEngine => f.write_str("Differential GNSS Engine"),
3034                Subsystem::Can => f.write_str("CAN"),
3035                Subsystem::WheelOdometry => f.write_str("Wheel Odometry"),
3036                Subsystem::SensorFusionEngine => f.write_str("Sensor Fusion Engine"),
3037            }
3038        }
3039    }
3040
3041    impl TryFrom<u16> for Subsystem {
3042        type Error = u16;
3043        fn try_from(i: u16) -> Result<Self, u16> {
3044            match i {
3045                0 => Ok(Subsystem::PrimaryGnssAntenna),
3046                1 => Ok(Subsystem::MeasurementEngine),
3047                2 => Ok(Subsystem::CorrectionsClient),
3048                3 => Ok(Subsystem::DifferentialGnssEngine),
3049                4 => Ok(Subsystem::Can),
3050                5 => Ok(Subsystem::WheelOdometry),
3051                6 => Ok(Subsystem::SensorFusionEngine),
3052                i => Err(i),
3053            }
3054        }
3055    }
3056
3057    /// Generic
3058    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3059    pub enum Generic {
3060        /// OK/Nominal
3061        OKNominal = 0,
3062
3063        /// Initializing
3064        Initializing = 1,
3065
3066        /// Unknown
3067        Unknown = 2,
3068
3069        /// Degraded
3070        Degraded = 3,
3071
3072        /// Unusable
3073        Unusable = 4,
3074    }
3075
3076    impl std::fmt::Display for Generic {
3077        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3078            match self {
3079                Generic::OKNominal => f.write_str("OK/Nominal"),
3080                Generic::Initializing => f.write_str("Initializing"),
3081                Generic::Unknown => f.write_str("Unknown"),
3082                Generic::Degraded => f.write_str("Degraded"),
3083                Generic::Unusable => f.write_str("Unusable"),
3084            }
3085        }
3086    }
3087
3088    impl TryFrom<u8> for Generic {
3089        type Error = u8;
3090        fn try_from(i: u8) -> Result<Self, u8> {
3091            match i {
3092                0 => Ok(Generic::OKNominal),
3093                1 => Ok(Generic::Initializing),
3094                2 => Ok(Generic::Unknown),
3095                3 => Ok(Generic::Degraded),
3096                4 => Ok(Generic::Unusable),
3097                i => Err(i),
3098            }
3099        }
3100    }
3101}