diff --git a/c/include/libsbp/system_macros.h b/c/include/libsbp/system_macros.h index fe6cad067f..8121fe768d 100644 --- a/c/include/libsbp/system_macros.h +++ b/c/include/libsbp/system_macros.h @@ -247,7 +247,7 @@ #define SBP_STATUS_REPORT_SYSTEM_STARLING (0) #define SBP_STATUS_REPORT_SYSTEM_PRECISION_GNSS_MODULE (1) -#define SBP_STATUS_REPORT_SBP_MAJOR_PROTOCOL_VERSION_NUMBER_MASK (0x1ff) +#define SBP_STATUS_REPORT_SBP_MAJOR_PROTOCOL_VERSION_NUMBER_MASK (0xff) #define SBP_STATUS_REPORT_SBP_MAJOR_PROTOCOL_VERSION_NUMBER_SHIFT (8u) #define SBP_STATUS_REPORT_SBP_MAJOR_PROTOCOL_VERSION_NUMBER_GET(flags) \ ((u16)( \ diff --git a/c/include/libsbp/version.h b/c/include/libsbp/version.h index ce4aac8776..870cb6d554 100644 --- a/c/include/libsbp/version.h +++ b/c/include/libsbp/version.h @@ -28,7 +28,7 @@ #define SBP_PATCH_VERSION 3 /** Full SBP version string. */ -#define SBP_VERSION "4.1.3" +#define SBP_VERSION "4.1.4-alpha" /** \} */ diff --git a/generator/sbpg/generator.py b/generator/sbpg/generator.py index 67092f0f70..b08013fef5 100755 --- a/generator/sbpg/generator.py +++ b/generator/sbpg/generator.py @@ -171,9 +171,6 @@ def main(): elif args.test_java: import sbpg.targets.test_java as test_java test_java.render_source(output_dir, parsed) - elif args.rust: - import sbpg.targets.rust as rs - rs.render_source(output_dir, parsed) elif args.test_rust: import sbpg.targets.test_rust as test_rs test_rs.render_source(output_dir, parsed) @@ -200,10 +197,9 @@ def main(): parsed = [yaml.parse_spec(spec) for _, spec in file_index_items] java.render_table(output_dir, parsed) elif args.rust: + import sbpg.targets.rust as rs parsed = [yaml.parse_spec(spec) for spec in file_index.values()] - rs.render_mod(output_dir, parsed) - rs.render_sbp_cargo_toml(output_dir, release) - rs.render_sbp2json_cargo_toml(output_dir, release) + rs.render_all(output_dir, parsed, release) elif args.test_c: test_c.render_check_suites(output_dir, all_specs) test_c.render_check_main(output_dir, all_specs) diff --git a/generator/sbpg/targets/resources/sbp2json-cargo.toml b/generator/sbpg/targets/resources/rust/sbp2json_cargo.toml similarity index 100% rename from generator/sbpg/targets/resources/sbp2json-cargo.toml rename to generator/sbpg/targets/resources/rust/sbp2json_cargo.toml diff --git a/generator/sbpg/targets/resources/sbp-cargo.toml b/generator/sbpg/targets/resources/rust/sbp_cargo.toml similarity index 100% rename from generator/sbpg/targets/resources/sbp-cargo.toml rename to generator/sbpg/targets/resources/rust/sbp_cargo.toml diff --git a/generator/sbpg/targets/resources/sbp_messages_mod.rs b/generator/sbpg/targets/resources/rust/sbp_messages_mod.rs similarity index 76% rename from generator/sbpg/targets/resources/sbp_messages_mod.rs rename to generator/sbpg/targets/resources/rust/sbp_messages_mod.rs index 4acbbf2f9d..66cbbb30ab 100644 --- a/generator/sbpg/targets/resources/sbp_messages_mod.rs +++ b/generator/sbpg/targets/resources/rust/sbp_messages_mod.rs @@ -14,13 +14,11 @@ pub mod (((m))); ((*- endfor *)) pub mod unknown; -((*- for p in packages *)) -((*- for m in p.definitions *)) +((*- for m in msgs *)) ((*- if m.is_real_message *)) -use self::(((p.identifier|mod_name)))::(((m.identifier|camel_case))); +use self::(((m.parent_mod_name)))::(((m.mod_name)))::(((m.msg_name))); ((*- endif *)) ((*- endfor *)) -((*- endfor *)) use self::unknown::Unknown; mod lib { @@ -28,14 +26,41 @@ mod lib { pub use std::convert::{TryFrom, TryInto}; - pub use crate::wire_format::{WireFormat, PayloadParseError}; - pub use crate::sbp_string::{SbpString, Unterminated, NullTerminated, Multipart, DoubleNullTerminated}; + pub use crate::sbp_string::{ + DoubleNullTerminated, Multipart, NullTerminated, SbpString, Unterminated, + }; #[cfg(feature = "swiftnav")] pub use crate::time; + pub use crate::wire_format::{PayloadParseError, WireFormat}; pub use super::{ConcreteMessage, Sbp, SbpMessage, TryFromSbpError}; pub use bytes::{Buf, BufMut}; + + macro_rules! get_bit_range { + ($bitrange:expr, $source_ty:ty, $target_ty:ty, $msb:expr, $lsb:expr) => {{ + let source_bit_len = std::mem::size_of::<$source_ty>() * 8; + let target_bit_len = std::mem::size_of::<$target_ty>() * 8; + let result = + (($bitrange << (source_bit_len - $msb - 1)) >> (source_bit_len - $msb - 1 + $lsb)) as $target_ty; + result << (target_bit_len - ($msb - $lsb + 1)) >> (target_bit_len - ($msb - $lsb + 1)) + }}; + } + + macro_rules! set_bit_range { + ($bitrange:expr, $value: expr, $source_ty:ty, $target_ty:ty, $msb:expr, $lsb:expr) => { + let source_bit_len = std::mem::size_of::<$source_ty>() * 8; + let mask: $source_ty = !(0 as $source_ty) + << (source_bit_len - $msb - 1) + >> (source_bit_len - $msb - 1 + $lsb) + << ($lsb); + *$bitrange &= !mask; + *$bitrange |= ($value as $source_ty << $lsb) & mask; + }; + } + + pub(crate) use get_bit_range; + pub(crate) use set_bit_range; } use lib::*; @@ -87,7 +112,7 @@ impl std::error::Error for TryFromSbpError {} pub enum Sbp { ((*- for m in msgs *)) /// (((m.short_desc | commentify(indent=2) ))) - (((m.identifier|camel_case)))( (((m.identifier|camel_case))) ), + (((m.msg_name)))( (((m.msg_name))) ), ((*- endfor *)) /// Unknown message type Unknown( Unknown ), @@ -122,10 +147,10 @@ impl Sbp { pub fn from_frame(mut frame: crate::Frame) -> Result { match frame.msg_type { ((*- for m in msgs *)) - (((m.identifier|camel_case)))::MESSAGE_TYPE => { - let mut msg = (((m.identifier|camel_case)))::parse(&mut frame.payload)?; + (((m.msg_name)))::MESSAGE_TYPE => { + let mut msg = (((m.msg_name)))::parse(&mut frame.payload)?; msg.set_sender_id(frame.sender_id); - Ok(Sbp::(((m.identifier|camel_case)))(msg)) + Ok(Sbp::(((m.msg_name)))(msg)) }, ((*- endfor *)) _ => { @@ -141,7 +166,7 @@ impl SbpMessage for Sbp { fn message_name(&self) -> &'static str { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.message_name() }, ((*- endfor *)) @@ -154,7 +179,7 @@ impl SbpMessage for Sbp { fn message_type(&self) -> u16 { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.message_type() }, ((*- endfor *)) @@ -167,7 +192,7 @@ impl SbpMessage for Sbp { fn sender_id(&self) -> Option { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.sender_id() }, ((*- endfor *)) @@ -180,7 +205,7 @@ impl SbpMessage for Sbp { fn set_sender_id(&mut self, new_id: u16) { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.set_sender_id(new_id) }, ((*- endfor *)) @@ -193,7 +218,7 @@ impl SbpMessage for Sbp { fn encoded_len(&self) -> usize { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.encoded_len() }, ((*- endfor *)) @@ -207,7 +232,7 @@ impl SbpMessage for Sbp { fn gps_time(&self) -> Option> { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { msg.gps_time() }, ((*- endfor *)) @@ -228,7 +253,7 @@ impl WireFormat for Sbp { fn write(&self, buf: &mut B) { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { WireFormat::write(msg, buf) }, ((*- endfor *)) @@ -241,7 +266,7 @@ impl WireFormat for Sbp { fn len(&self) -> usize { match self { ((*- for m in msgs *)) - Sbp::(((m.identifier|camel_case)))(msg) => { + Sbp::(((m.msg_name)))(msg) => { WireFormat::len(msg) }, ((*- endfor *)) @@ -253,9 +278,9 @@ impl WireFormat for Sbp { } ((* for m in msgs *)) -impl From<(((m.identifier|camel_case)))> for Sbp { - fn from(msg: (((m.identifier|camel_case)))) -> Self { - Sbp::(((m.identifier|camel_case)))(msg) +impl From<(((m.msg_name)))> for Sbp { + fn from(msg: (((m.msg_name)))) -> Self { + Sbp::(((m.msg_name)))(msg) } } diff --git a/generator/sbpg/targets/resources/rust/sbp_messages_template.rs b/generator/sbpg/targets/resources/rust/sbp_messages_template.rs new file mode 100644 index 0000000000..3cbd72f324 --- /dev/null +++ b/generator/sbpg/targets/resources/rust/sbp_messages_template.rs @@ -0,0 +1,233 @@ +// Copyright (C) 2015-2021 Swift Navigation Inc. +// Contact: https://support.swiftnav.com +// +// This source is subject to the license found in the file 'LICENSE' which must +// be be distributed together with this source. All other rights reserved. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + +//**************************************************************************** +// Automatically generated from yaml/(((filepath))) +// with generate.py. Please do not hand edit! +//****************************************************************************/ + +//! (((description | commentify(prefix="//! ") ))) + + +((*- for m in msgs *)) +pub use (((m.mod_name)))::(((m.msg_name))); +((*- endfor *)) + + + +((* for m in msgs *)) +pub mod (((m.mod_name))) { +#![allow(unused_imports)] + +use super::*; +use crate::messages::lib::*; +((*- for i in includes *)) +use crate::messages::(((i)))::*; +((*- endfor *)) + +((*- if m.desc *)) + +/// (((m.short_desc))) +/// +/// (((m.desc | commentify))) +/// +((*- elif m.short_desc *)) +/// (((m.short_desc))) +((*- endif *)) +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[derive(Debug, Clone)] +pub struct (((m.msg_name))) { + ((*- if m.is_real_message *)) + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + ((*- endif *)) + ((*- for f in m.fields *)) + ((*- if f.desc *)) + /// (((f.desc | commentify(indent=2) ))) + ((*- endif *)) + #[cfg_attr(feature = "serde", serde(rename(serialize = "(((f.identifier)))")))] + pub (((f.field_name))): (((f.type))), + ((*- endfor *)) +} + +((= create getters/setters for bitfields if appropriate =)) + +((* if m.has_bitfield *)) +impl (((m.msg_name))) { +((* for f in m.fields *)) +((* for b in f.bitfield *)) + +((* if b.vals|length > 0 *)) + /// Gets the [(((b.type_name)))][self::(((b.type_name)))] stored in the `(((b.field)))` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `(((b.type_name)))` variant. + /// Otherwise the value of the bitrange is returned as an `Err((( '(' )))(((b.type)))((( ')' )))`. This may be because of a malformed message, + /// or because new variants of `(((b.type_name)))` were added. + pub fn (((b.bitrange_name))) (&self) -> Result<(((b.type_name))), (((b.type)))> { + get_bit_range!( self.(((b.field))), (((f.type))), (((b.type))), (((b.msb))), (((b.lsb))) ).try_into() + } + + /// Set the bitrange corresponding to the [(((b.type_name)))][(((b.type_name)))] of the `(((b.field)))` bitfield. + pub fn set_(((b.bitrange_name))) (&mut self, (((b.bitrange_name))): (((b.type_name)))) { + set_bit_range!(&mut self.(((b.field))), (((b.bitrange_name))), (((f.type))), (((b.type))), (((b.msb))), (((b.lsb))) ); + } +((* elif b.type == "bool" *)) + /// Gets the `(((b.bitrange_name)))` flag. + pub fn (((b.bitrange_name))) (&self) -> bool { + ( ( self.(((b.field))) >> (((b.msb))) ) & 1) == 1 + } + + /// Sets the `(((b.bitrange_name)))` flag. + pub fn set_(((b.bitrange_name))) (&mut self, (((b.bitrange_name))): (((b.type)))) { + self.(((b.field))) ^= ( !( (((b.bitrange_name))) as (((f.type))) ) ) & (1 << (((b.msb))) ) + } +((* else *)) + /// Gets the `(((b.bitrange_name)))` stored in `(((b.field)))`. + pub fn (((b.bitrange_name))) (&self) -> (((b.type))) { + get_bit_range!( self.(((b.field))), (((f.type))), (((b.type))), (((b.msb))), (((b.lsb))) ) + } + + /// Sets the `(((b.bitrange_name)))` bitrange of `(((b.field)))`. + pub fn set_(((b.bitrange_name))) (&mut self, (((b.bitrange_name))): (((b.type)))) { + set_bit_range!(&mut self.(((b.field))), (((b.bitrange_name))), (((f.type))), (((b.type))), (((b.msb))), (((b.lsb))) ); + } +((* endif *)) + +((* endfor *)) +((* endfor *)) +} +((* endif *)) + +((= implement various traits for the message =)) + +((* if m.is_real_message *)) +impl ConcreteMessage for (((m.msg_name))) { + const MESSAGE_TYPE: u16 = (((m.sbp_id))); + const MESSAGE_NAME: &'static str = "(((m.identifier)))"; +} + +impl SbpMessage for (((m.msg_name))) { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + (((m.gps_time_fn))) +} + +impl TryFrom for (((m.msg_name))) { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::(((m.msg_name)))(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } +} +((* endif *)) + +impl WireFormat for (((m.msg_name))) { + const MIN_LEN: usize = + ((*- if not m.fields *)) + 0 + ((*- else *)) + < (((m.fields[0].type))) as WireFormat>::MIN_LEN + ((*- for f in m.fields[1:] *)) + + < (((f.type))) as WireFormat>::MIN_LEN + ((*- endfor *)) + ((*- endif *)); + fn len(&self) -> usize { + ((*- if not m.fields *)) + 0 + ((*- else *)) + WireFormat::len( &self.(((m.fields[0].field_name))) ) + ((*- for f in m.fields[1:] *)) + + WireFormat::len( &self.(((f.field_name))) ) + ((*- endfor *)) + ((*- endif *)) + } + fn write(&self, ((*- if not m.fields *)) _buf ((*- else *)) buf ((*- endif *)): &mut B) { + ((*- for f in m.fields *)) + WireFormat::write( &self.(((f.field_name))), buf); + ((*- endfor *)) + } + fn parse_unchecked( ((*- if not m.fields *)) _buf ((*- else *)) buf ((*- endif *)): &mut B) -> Self { + (((m.msg_name))) { + ((*- if m.is_real_message *)) + sender_id: None, + ((*- endif *)) + ((*- for f in m.fields *)) + (((f.field_name))): WireFormat::parse_unchecked(buf), + ((*- endfor *)) + } + } +} + +((= create types for bitfields if appropriate =)) + +((* if m.has_bitfield *)) +((* for f in m.fields *)) + +((* for b in f.bitfield *)) + +((* if b.vals|length > 0 *)) +((*- if b.desc *)) +/// (((b.desc | commentify))) +((*- endif *)) +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum (((b.type_name))) { + ((* for v in b.vals *)) + /// (((v.desc | commentify(indent=2) ))) + (((v.name))) = (((v.value))), + ((* endfor *)) +} + +impl std::fmt::Display for (((b.type_name))) { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ((*- for v in b.vals *)) + (((b.type_name)))::(((v.name))) => f.write_str("(((v.desc)))"), + ((*- endfor *)) + } + } +} + +impl TryFrom<(((b.type)))> for (((b.type_name))) { + type Error = (((b.type))); + fn try_from(i: (((b.type))) ) -> Result { + match i { + ((*- for v in b.vals *)) + (((v.value))) => Ok( (((b.type_name))) :: (((v.name))) ), + ((*- endfor *)) + i => Err(i), + } + } +} +((* endif *)) + +((* endfor *)) + +((* endfor *)) +((* endif *)) + +} + +((* endfor *)) diff --git a/generator/sbpg/targets/resources/sbp_tests_main_template.rs b/generator/sbpg/targets/resources/rust/test/sbp_tests_main_template.rs similarity index 100% rename from generator/sbpg/targets/resources/sbp_tests_main_template.rs rename to generator/sbpg/targets/resources/rust/test/sbp_tests_main_template.rs diff --git a/generator/sbpg/targets/resources/sbp_tests_template.rs b/generator/sbpg/targets/resources/rust/test/sbp_tests_template.rs similarity index 100% rename from generator/sbpg/targets/resources/sbp_tests_template.rs rename to generator/sbpg/targets/resources/rust/test/sbp_tests_template.rs diff --git a/generator/sbpg/targets/resources/sbp_messages_template.rs b/generator/sbpg/targets/resources/sbp_messages_template.rs deleted file mode 100644 index fe792bd91e..0000000000 --- a/generator/sbpg/targets/resources/sbp_messages_template.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (C) 2015-2021 Swift Navigation Inc. -// Contact: https://support.swiftnav.com -// -// This source is subject to the license found in the file 'LICENSE' which must -// be be distributed together with this source. All other rights reserved. -// -// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, -// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. - -//**************************************************************************** -// Automatically generated from yaml/(((filepath))) -// with generate.py. Please do not hand edit! -//****************************************************************************/ - -//! (((description | commentify(prefix="//! ") ))) - -((* for i in includes *)) -use super::(((i)))::*; -((* endfor *)) - -use super::lib::*; - -((* for m in msgs *)) -((*- if m.desc *)) -/// (((m.short_desc))) -/// -/// (((m.desc | commentify))) -/// -((*- elif m.short_desc *)) -/// (((m.short_desc))) -((*- endif *)) -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct (((m.identifier|camel_case))) { - ((*- if m.is_real_message *)) - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - ((*- endif *)) - ((*- for f in m.fields *)) - ((*- if f.desc *)) - /// (((f.desc | commentify(indent=2) ))) - ((*- endif *)) - #[cfg_attr(feature = "serde", serde(rename(serialize = "(((f.identifier)))")))] - pub (((f.identifier|snake_case))): (((f|type_map))), - ((*- endfor *)) -} - -((* if m.is_real_message *)) -impl ConcreteMessage for (((m.identifier|camel_case))) { - const MESSAGE_TYPE: u16 = (((m.sbp_id))); - const MESSAGE_NAME: &'static str = "(((m.identifier)))"; -} - -impl SbpMessage for (((m.identifier|camel_case))) { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - (((m|gps_time(msgs)))) -} - -impl TryFrom for (((m.identifier|camel_case))) { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::(((m.identifier|camel_case)))(m) => Ok(m), - _ => Err(TryFromSbpError), - } - } -} -((* endif *)) - -impl WireFormat for (((m.identifier|camel_case))) { - const MIN_LEN: usize = - ((*- if not m.fields *)) - 0 - ((*- else *)) - < (((m.fields[0]|type_map))) as WireFormat>::MIN_LEN - ((*- for f in m.fields[1:] *)) - + < (((f|type_map))) as WireFormat>::MIN_LEN - ((*- endfor *)) - ((*- endif *)); - fn len(&self) -> usize { - ((*- if not m.fields *)) - 0 - ((*- else *)) - WireFormat::len( &self.(((m.fields[0].identifier|snake_case))) ) - ((*- for f in m.fields[1:] *)) - + WireFormat::len( &self.(((f.identifier|snake_case))) ) - ((*- endfor *)) - ((*- endif *)) - } - fn write(&self, ((*- if not m.fields *)) _buf ((*- else *)) buf ((*- endif *)): &mut B) { - ((*- for f in m.fields *)) - WireFormat::write( &self.(((f.identifier|snake_case))), buf); - ((*- endfor *)) - } - fn parse_unchecked( ((*- if not m.fields *)) _buf ((*- else *)) buf ((*- endif *)): &mut B) -> Self { - (((m.identifier|camel_case))) { - ((*- if m.is_real_message *)) - sender_id: None, - ((*- endif *)) - ((*- for f in m.fields *)) - (((f.identifier|snake_case))): WireFormat::parse_unchecked(buf), - ((*- endfor *)) - } - } -} -((* endfor *)) diff --git a/generator/sbpg/targets/rust.py b/generator/sbpg/targets/rust.py index 18b18a67ed..e9ea9b6889 100644 --- a/generator/sbpg/targets/rust.py +++ b/generator/sbpg/targets/rust.py @@ -19,11 +19,11 @@ from sbpg.targets.templating import JENV, ACRONYMS, LOWER_ACRONYMS, indented_wordwrap from sbpg import ReleaseVersion -SBP_CARGO_TEMPLATE = "sbp-cargo.toml" -SBP2JSON_CARGO_TEMPLATE = "sbp2json-cargo.toml" +SBP_CARGO_TEMPLATE = "rust/sbp_cargo.toml" +SBP2JSON_CARGO_TEMPLATE = "rust/sbp2json_cargo.toml" +MESSAGES_TEMPLATE_NAME = "rust/sbp_messages_template.rs" +MESSAGES_MOD_TEMPLATE_NAME = "rust/sbp_messages_mod.rs" -MESSAGES_TEMPLATE_NAME = "sbp_messages_template.rs" -MESSAGES_MOD_TEMPLATE_NAME = "sbp_messages_mod.rs" GPS_TIME = """ let tow_s = (self.tow as f64) / 1000.0; @@ -59,7 +59,7 @@ BASE_TIME_MSGS = ["MSG_OBS", "MSG_OSR", "MSG_SSR"] CUSTOM_GPS_TIME_MSGS = { - "MSG_IMU_RAW": """ + "MSG_IMU_RAW": """ const IMU_RAW_TIME_STATUS_MASK: u32 = (1 << 30) | (1 << 31); if self.tow & IMU_RAW_TIME_STATUS_MASK != 0 { return None; @@ -70,8 +70,7 @@ Err(e) => return Some(Err(e.into())), }; """.strip(), - - "MSG_WHEELTICK": """ + "MSG_WHEELTICK": """ // only consider wheelticks with synchronization type value "microsec in GPS week" if self.flags != 1 { return None; @@ -85,131 +84,137 @@ } import re + + def camel_case(s): - """ - Makes a classname. - """ - if '_' not in s: return lower_acronyms(s) - s = re.sub('([a-z])([A-Z])', r'\1_\2', s) - return ''.join(w.title() for w in s.split('_')) + """ + Makes a classname. + """ + if "_" not in s: + if s[0].islower(): + s = s[0].upper() + s[1:] + return lower_acronyms(s) + s = re.sub("([a-z])([A-Z])", r"\1_\2", s) + return "".join(w.title() for w in s.split("_")) + def snake_case(s): - if "_" in s: - return "_".join(snake_case(p) for p in s.split('_')) - if len(s) == 1: - return s.lower() - s = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', s) - return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s).lower() + if "_" in s: + return "_".join(snake_case(p) for p in s.split("_")) + if len(s) == 1: + return s.lower() + s = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", s) + return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s).lower() + def lower_acronyms(s): - acronyms = ACRONYMS + ["GNSS", "IMU"] - lower_acronyms = LOWER_ACRONYMS + ["Gnss", "Imu"] - for (i, a) in enumerate(acronyms): - s = s.replace(a, lower_acronyms[i]) - return s + acronyms = ACRONYMS + ["GNSS", "IMU"] + lower_acronyms = LOWER_ACRONYMS + ["Gnss", "Imu"] + for (i, a) in enumerate(acronyms): + s = s.replace(a, lower_acronyms[i]) + return s -@pass_environment -def commentify(environment: Environment, - value: str, - indent: int=0, - prefix: str="/// "): - """ - Builds a comment. - """ - value = indented_wordwrap(environment, value, indent=(" " * indent) + prefix, first=False, markdown=True) - value = wrap_urls(value) - value = escape_braces(value) - return value def wrap_urls(s): - urls = re.findall(r"\(?https?://[^\s\)]+\)?", s) - for url in urls: - if url.startswith("(") and url.endswith(")"): - continue - if url.endswith(")"): - s = s.replace(url, "<" + url[:-1] + ">)") - else: - s = s.replace(url, "<" + url + ">") - return s + urls = re.findall(r"\(?https?://[^\s\)]+\)?", s) + for url in urls: + if url.startswith("(") and url.endswith(")"): + continue + if url.endswith(")"): + s = s.replace(url, "<" + url[:-1] + ">)") + else: + s = s.replace(url, "<" + url + ">") + return s + def escape_braces(s): - groups = re.findall(r"(\[[^\]]+\])[^\(]", s) - for group in groups: - s = s.replace(group, "\\" + group[:-1] + "\]") - return s - -TYPE_MAP = {'u8': 'u8', - 'u16': 'u16', - 'u32': 'u32', - 'u64': 'u64', - 's8': 'i8', - 's16': 'i16', - 's32': 'i32', - 's64': 'i64', - 'float': 'f32', - 'double': 'f64'} + groups = re.findall(r"(\[[^\]]+\])[^\(]", s) + for group in groups: + s = s.replace(group, "\\" + group[:-1] + "\]") + return s -def type_map(field): - if field.type_id in TYPE_MAP: - return TYPE_MAP[field.type_id] - if field.type_id == 'array': - t = field.options['fill'].value - if 'size' in field.options: - return "[{}; {}]".format(TYPE_MAP.get(t, t), field.options['size'].value) - else: - return "Vec<{}>".format(TYPE_MAP.get(t, t)) - - if field.type_id == "string": - if 'encoding' in field.options: - e = field.options['encoding'].value - if e == "unterminated": - encoding = "Unterminated" - elif e == "null_terminated": - encoding = "NullTerminated" - elif e == "multipart": - encoding = "Multipart" - elif e == "double_null_terminated": - encoding = "DoubleNullTerminated" - else: - encoding = "Unterminated" - if 'size' in field.options: - return "SbpString<[u8; {}], {}>".format(field.options['size'].value, encoding) - else: - return "SbpString, {}>".format(encoding) +@pass_environment +def commentify( + environment: Environment, value: str, indent: int = 0, prefix: str = "/// " +): + """ + Builds a comment. + """ + value = indented_wordwrap( + environment, value, indent=(" " * indent) + prefix, first=False, markdown=True + ) + value = wrap_urls(value) + value = escape_braces(value) + return value + + +JENV.filters["commentify"] = commentify + + +TYPE_MAP = { + "u8": "u8", + "u16": "u16", + "u32": "u32", + "u64": "u64", + "s8": "i8", + "s16": "i16", + "s32": "i32", + "s64": "i64", + "float": "f32", + "double": "f64", +} + - return lower_acronyms(field.type_id) +def type_map(field): + if field.type_id in TYPE_MAP: + return TYPE_MAP[field.type_id] + + if field.type_id == "array": + t = field.options["fill"].value + if "size" in field.options: + return "[{}; {}]".format(TYPE_MAP.get(t, t), field.options["size"].value) + else: + return "Vec<{}>".format(TYPE_MAP.get(t, t)) + + if field.type_id == "string": + if "encoding" in field.options: + e = field.options["encoding"].value + if e == "unterminated": + encoding = "Unterminated" + elif e == "null_terminated": + encoding = "NullTerminated" + elif e == "multipart": + encoding = "Multipart" + elif e == "double_null_terminated": + encoding = "DoubleNullTerminated" + else: + encoding = "Unterminated" + if "size" in field.options: + return "SbpString<[u8; {}], {}>".format( + field.options["size"].value, encoding + ) + else: + return "SbpString, {}>".format(encoding) -def mod_name(x): - return x.split('.', 2)[2] + return lower_acronyms(field.type_id) -def gps_time(msg, all_messages): - def time_aware_header(type_id): - for m in all_messages: - if m.identifier == type_id: - return any([f.identifier == "t" for f in m.fields]) - return False +def gps_time_fn(msg): def gen_body(): if msg.identifier in CUSTOM_GPS_TIME_MSGS: - return CUSTOM_GPS_TIME_MSGS[msg.identifier] - - header = False + return CUSTOM_GPS_TIME_MSGS[msg.identifier] tow = False wn = False - for f in msg.fields: - if f.identifier == "header" and time_aware_header(f.type_id): - header = True + if f.has_gps_time: + return GPS_TIME_HEADER elif f.identifier == "tow": assert f.units == "ms" tow = True elif f.identifier == "wn": wn = True - - if header: - return GPS_TIME_HEADER - elif tow and wn: + if tow and wn: return GPS_TIME elif tow: return GPS_TIME_ONLY_TOW @@ -220,12 +225,12 @@ def gen_ret(): name = "Base" if msg.identifier in BASE_TIME_MSGS else "Rover" return f"Some(Ok(time::MessageTime::{name}(gps_time.into())))" + if not msg.is_real_message: + return "" body = gen_body() if body is None: return "" - ret = gen_ret() - return f""" #[cfg(feature = "swiftnav")] fn gps_time(&self) -> Option> {{ @@ -235,65 +240,192 @@ def gen_ret(): """.strip() -JENV.filters['camel_case'] = camel_case -JENV.filters['commentify'] = commentify -JENV.filters['type_map'] = type_map -JENV.filters['mod_name'] = mod_name -JENV.filters['gps_time'] = gps_time -JENV.filters['wrap_urls'] = wrap_urls -JENV.filters['snake_case'] = snake_case - -def render_source(output_dir, package_spec): - """ - Render and output to a directory given a package specification. - """ - _, name = package_spec.filepath - destination_filename = "%s/sbp/src/messages/%s.rs" % (output_dir, name) - py_template = JENV.get_template(MESSAGES_TEMPLATE_NAME) - includes = [x.rsplit('.', 1)[0] for x in package_spec.includes] - if 'types' in includes: - del includes[includes.index('types')] - with open(destination_filename, 'w') as f: - f.write(py_template.render(msgs=sorted(package_spec.definitions, key=lambda msg: msg.identifier), - pkg_name=name, - filepath="/".join(package_spec.filepath) + ".yaml", - description=package_spec.description, - timestamp=package_spec.creation_timestamp, - includes=includes)) - -def render_mod(output_dir, package_specs): - msgs = [] - mods = [] - for package_spec in package_specs: - if not package_spec.render_source: - continue - name = package_spec.identifier.split('.', 2)[2] - if name != 'types': - mods.append(name) - for m in package_spec.definitions: - if m.is_real_message: - msgs.append(m) - destination_filename = "%s/sbp/src/messages/mod.rs" % output_dir - py_template = JENV.get_template(MESSAGES_MOD_TEMPLATE_NAME) - with open(destination_filename, 'w') as f: - f.write(py_template.render(packages=package_specs, - mods=mods, - msgs=sorted(msgs, key=lambda msg: msg.sbp_id))) - - -def render_sbp_cargo_toml(output_dir, release: ReleaseVersion): - destination_filename = "%s/sbp/Cargo.toml" % output_dir - py_template = JENV.get_template(SBP_CARGO_TEMPLATE) - with open(destination_filename, 'w') as f: - f.write(py_template.render(release=release.full_version)) - - -def render_sbp2json_cargo_toml(output_dir, release: ReleaseVersion): - destination_filename = "%s/sbp2json/Cargo.toml" % output_dir - py_template = JENV.get_template(SBP2JSON_CARGO_TEMPLATE) - if '-alpha' not in release.full_version: - version = "%s-unreleased" % (release.full_version,) - else: - version = release.full_version - with open(destination_filename, 'w') as f: - f.write(py_template.render(release=version)) +def get_bitfield_basename(item, field): + if item.get("desc", False): + basename = camel_case(item.get("desc", "").replace(" ", "_")) + else: + basename = camel_case(field.identifier) + basename = re.sub("[^A-Za-z0-9_]+", "", basename) + return basename + + +def calc_item_size(item, field): + int_types = [8, 16, 32, 64] + length = int(item.get("len")) - 1 + for i in int_types: + if i >= length: + return f"u{i}" + + +def get_bitfield_values(item): + vals = [] + for val in item.get("vals", []): + name = val.get("desc", None) + name = re.sub(r"\([^)]*\)", "", name) + name = re.sub("[ \-]+", "_", name.strip()) + name = re.sub("[^A-Za-z0-9_]+", "", name) + name = camel_case(name) + if name.lower() == "reserved": + continue + if name[0].isnumeric(): + name = "_" + name + vals.append( + { + "name": name, + "value": int(val.get("value")), + "desc": val.get("desc", ""), + } + ) + return vals + + +def get_bitfield(field): + items = [] + for item in field.options["fields"].value: + type_name = get_bitfield_basename(item, field) + if type_name.endswith("Reserved"): + continue + vals = get_bitfield_values(item) + if len(vals) == 0: + type_name = field.type + if item.get("desc", False): + field_name = snake_case(item.get("desc", "").replace(" ", "_")) + field_name = re.sub("[^A-Za-z0-9_]+", "", field_name) + else: + field_name = snake_case(field.identifier) + field_name = re.sub("__", "_", field_name) + bitrange = item.get("range").split(":") + is_bool = False + if len(bitrange) == 1: + msb = int(bitrange[0]) + lsb = msb + is_bool = len(vals) == 0 + else: + msb = int(bitrange[1]) + lsb = int(bitrange[0]) + items.append( + { + "desc": item.get("desc"), + "field": field.field_name, + "msb": msb, + "lsb": lsb, + "type_name": type_name, + "type": "bool" if is_bool else calc_item_size(item, field), + "bitrange_name": field_name, + "vals": vals, + } + ) + return items + + +class FieldItem(object): + def __init__(self, msg, package_specs, field): + self.identifier = field.identifier + self.type_id = field.type_id + self.units = field.units + self.desc = field.desc + self.options = field.options + self.field_name = snake_case(self.identifier) + self.type = type_map(field) + self.has_gps_time = False + self.msg = msg + for pkg in package_specs: + for m in pkg.definitions: + if m.identifier == self.type_id and any( + f.identifier == "t" for f in m.fields + ): + self.has_gps_time = True + self.bitfield = [] + if self.options.get("fields", False): + self.bitfield = get_bitfield(self) + + +class MsgItem(object): + def __init__(self, msg, package, package_specs): + self.msg_name = camel_case(msg.identifier) + self.parent_mod_name = package.mod_name + self.mod_name = snake_case(msg.identifier) + self.identifier = msg.identifier + self.sbp_id = msg.sbp_id + self.desc = msg.desc + self.short_desc = msg.short_desc + self.is_real_message = msg.is_real_message + self.fields = [] + self.has_bitfield = False + for f in msg.fields: + field = FieldItem(msg, package_specs, f) + self.fields.append(field) + if len(field.bitfield) > 0: + self.has_bitfield = True + self.gps_time_fn = gps_time_fn(self) + + +class PackageItem(object): + def __init__(self, package, package_specs): + self.identifier = package.identifier + self.description = package.description + self.creation_timestamp = package.creation_timestamp + self.mod_name = package.identifier.split(".", 2)[2] + self.filepath = package.filepath + self.includes = [inc.rsplit(".", 1)[0] for inc in package.includes] + if "types" in self.includes: + del self.includes[self.includes.index("types")] + self.msgs = [] + for msg in sorted(package.definitions, key=lambda pkg: pkg.identifier): + msg = MsgItem(msg, self, package_specs) + self.msgs.append(msg) + + +def render_all(output_dir, package_specs, release: ReleaseVersion): + pkgs = [] + msgs = [] + for package_spec in package_specs: + if not package_spec.render_source: + continue + pkg = PackageItem(package_spec, package_specs) + if pkg.mod_name == "types" or pkg.mod_name == "base": + continue + pkgs.append(pkg) + for m in pkg.msgs: + if m.is_real_message: + msgs.append(m) + for pkg in pkgs: + render_file( + MESSAGES_TEMPLATE_NAME, + f"{output_dir}/sbp/src/messages/{pkg.mod_name}.rs", + { + "msgs": pkg.msgs, + "filepath": "/".join(pkg.filepath) + ".yaml", + "description": pkg.description, + "timestamp": pkg.creation_timestamp, + "includes": pkg.includes, + }, + ) + render_file( + MESSAGES_MOD_TEMPLATE_NAME, + f"{output_dir}/sbp/src/messages/mod.rs", + { + "mods": [pkg.mod_name for pkg in pkgs], + "msgs": sorted(msgs, key=lambda msg: msg.sbp_id), + }, + ) + render_file( + SBP_CARGO_TEMPLATE, + f"{output_dir}/sbp/Cargo.toml", + {"release": release.full_version}, + ) + if "-alpha" not in release.full_version: + version = f"{release.full_version}-unreleased" + else: + version = release.full_version + render_file( + SBP2JSON_CARGO_TEMPLATE, + f"{output_dir}/sbp2json/Cargo.toml", + {"release": version}, + ) + + +def render_file(template, destination_filename, args): + py_template = JENV.get_template(template) + with open(destination_filename, "w") as f: + f.write(py_template.render(**args)) diff --git a/generator/sbpg/targets/test_rust.py b/generator/sbpg/targets/test_rust.py index a16192d1ff..536a926322 100644 --- a/generator/sbpg/targets/test_rust.py +++ b/generator/sbpg/targets/test_rust.py @@ -19,8 +19,8 @@ from sbpg.targets.templating import JENV from sbpg.targets.rust import lower_acronyms, snake_case -TEST_TEMPLATE_NAME = "sbp_tests_template.rs" -TEST_MAIN_TEMPLATE_NAME = "sbp_tests_main_template.rs" +TEST_TEMPLATE_NAME = "rust/test/sbp_tests_template.rs" +TEST_MAIN_TEMPLATE_NAME = "rust/test/sbp_tests_main_template.rs" def str_escape(value): return "\"{}\".to_string()".format(value) diff --git a/rust/sbp/Cargo.toml b/rust/sbp/Cargo.toml index 80d398cb6c..17647d0b5d 100644 --- a/rust/sbp/Cargo.toml +++ b/rust/sbp/Cargo.toml @@ -7,7 +7,7 @@ [package] name = "sbp" -version = "4.1.3" +version = "4.1.4-alpha" description = "Rust native implementation of SBP (Swift Binary Protocol) for communicating with devices made by Swift Navigation" authors = ["Swift Navigation "] repository = "https://github.com/swift-nav/libsbp" diff --git a/rust/sbp/src/lib.rs b/rust/sbp/src/lib.rs index 36163d8a97..9caad6a6fa 100644 --- a/rust/sbp/src/lib.rs +++ b/rust/sbp/src/lib.rs @@ -64,6 +64,83 @@ //! process::exit(1); //! } //! } +//! +//! ``` +//! +//! # Bitfield Types +//! +//! A number of messages have fields that encode multiple values using a [bitfield](https://en.wikipedia.org/wiki/Bit_field). +//! This crate provides getters and setters on messages with these values. The getters and setters +//! have slightly different semantics that can be grouped into three categories. +//! +//! ## Enumerations +//! +//! Most bitfield members are mapped to a dataless enum. The setter accepts a variant of that enum. +//! The getter will return a variant of this enum wrapped in a `Result`. The getter returns `Ok` +//! if the bitfield member contains a known variant of the enum. Otherwise, the integral value of the +//! bitfield member is returned in the `Err` variant. This may be because of a malformed message, +//! or because you're SBP client is outdated and new variants of the enum were added. +//! +//! ``` +//! # use sbp::messages::navigation::msg_pos_llh::{FixMode, MsgPosLlh}; +//! # let msg = MsgPosLlh { +//! # sender_id: None, +//! # tow: 0, +//! # lat: 0., +//! # lon: 0., +//! # height: 0., +//! # h_accuracy: 0, +//! # v_accuracy: 0, +//! # n_sats: 0, +//! # flags: 0, +//! # }.into(); +//! let mut msg = MsgPosLlh::from(msg); +//! msg.set_fix_mode(FixMode::DeadReckoning); +//! assert_eq!(msg.fix_mode(), Ok(FixMode::DeadReckoning)); +//! ``` +//! +//! ## Integral +//! +//! Some bitfield members are represented by an integral type. In this case, the getter accepts the +//! smallest integer type that can contain the bitfield member. For example, if the bitfield member +//! spans 6 bits, the setter will accept a `u8`, and mask off any extra bits when setting the value. +//! The getter will return the integer value, again using the smallest integer type that will contain +//! the bitfield member. +//! +//! ``` +//! # use sbp::messages::system::MsgStatusReport; +//! # let msg = MsgStatusReport { +//! # sender_id: None, +//! # reporting_system: 0, +//! # sbp_version: 0, +//! # sequence: 0, +//! # uptime: 0, +//! # status: Vec::new(), +//! # }.into(); +//! let mut msg = MsgStatusReport::from(msg); +//! msg.set_sbp_major_protocol_version_number(3); +//! assert_eq!(msg.sbp_major_protocol_version_number(), 3); +//! ``` +//! +//! ## Boolean +//! +//! If the bitfield members is represented by a single bit, getters and setters use `bool`s. +//! +//! ``` +//! # use sbp::messages::navigation::MsgDops; +//! # let msg = MsgDops { +//! # sender_id: None, +//! # tow: 0, +//! # gdop: 0, +//! # pdop: 0, +//! # tdop: 0, +//! # hdop: 0, +//! # vdop: 0, +//! # flags: 0, +//! # }.into(); +//! let mut msg = MsgDops::from(msg); +//! msg.set_raim_repair_flag(true); +//! assert!(msg.raim_repair_flag()); //! ``` pub mod messages; diff --git a/rust/sbp/src/messages/acquisition.rs b/rust/sbp/src/messages/acquisition.rs index 7745bf5605..1f3457bb5c 100644 --- a/rust/sbp/src/messages/acquisition.rs +++ b/rust/sbp/src/messages/acquisition.rs @@ -13,692 +13,760 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Satellite acquisition messages from the device. - -use super::gnss::*; - -use super::lib::*; - -/// Acq perfomance measurement and debug -/// -/// Profile for a specific SV for debugging purposes. The message describes SV -/// profile during acquisition time. The message is used to debug and measure -/// the performance. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct AcqSvProfile { - /// SV search job type (deep, fallback, etc) - #[cfg_attr(feature = "serde", serde(rename(serialize = "job_type")))] - pub job_type: u8, - /// Acquisition status 1 is Success, 0 is Failure - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: u8, - /// CN0 value. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u16, - /// Acquisition integration time - #[cfg_attr(feature = "serde", serde(rename(serialize = "int_time")))] - pub int_time: u8, - /// GNSS signal for which acquisition was attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Acq frequency bin width - #[cfg_attr(feature = "serde", serde(rename(serialize = "bin_width")))] - pub bin_width: u16, - /// Timestamp of the job complete event - #[cfg_attr(feature = "serde", serde(rename(serialize = "timestamp")))] - pub timestamp: u32, - /// Time spent to search for sid.code - #[cfg_attr(feature = "serde", serde(rename(serialize = "time_spent")))] - pub time_spent: u32, - /// Doppler range lowest frequency - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_min")))] - pub cf_min: i32, - /// Doppler range highest frequency - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_max")))] - pub cf_max: i32, - /// Doppler value of detected peak. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: i32, - /// Codephase of detected peak. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: u32, -} - -impl WireFormat for AcqSvProfile { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.job_type) - + WireFormat::len(&self.status) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.int_time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.bin_width) - + WireFormat::len(&self.timestamp) - + WireFormat::len(&self.time_spent) - + WireFormat::len(&self.cf_min) - + WireFormat::len(&self.cf_max) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.cp) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.job_type, buf); - WireFormat::write(&self.status, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.int_time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.bin_width, buf); - WireFormat::write(&self.timestamp, buf); - WireFormat::write(&self.time_spent, buf); - WireFormat::write(&self.cf_min, buf); - WireFormat::write(&self.cf_max, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.cp, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - AcqSvProfile { - job_type: WireFormat::parse_unchecked(buf), - status: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - int_time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - bin_width: WireFormat::parse_unchecked(buf), - timestamp: WireFormat::parse_unchecked(buf), - time_spent: WireFormat::parse_unchecked(buf), - cf_min: WireFormat::parse_unchecked(buf), - cf_max: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), +pub use acq_sv_profile::AcqSvProfile; +pub use acq_sv_profile_dep::AcqSvProfileDep; +pub use msg_acq_result::MsgAcqResult; +pub use msg_acq_result_dep_a::MsgAcqResultDepA; +pub use msg_acq_result_dep_b::MsgAcqResultDepB; +pub use msg_acq_result_dep_c::MsgAcqResultDepC; +pub use msg_acq_sv_profile::MsgAcqSvProfile; +pub use msg_acq_sv_profile_dep::MsgAcqSvProfileDep; + +pub mod acq_sv_profile { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Acq perfomance measurement and debug + /// + /// Profile for a specific SV for debugging purposes. The message describes SV + /// profile during acquisition time. The message is used to debug and measure + /// the performance. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct AcqSvProfile { + /// SV search job type (deep, fallback, etc) + #[cfg_attr(feature = "serde", serde(rename(serialize = "job_type")))] + pub job_type: u8, + /// Acquisition status 1 is Success, 0 is Failure + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: u8, + /// CN0 value. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u16, + /// Acquisition integration time + #[cfg_attr(feature = "serde", serde(rename(serialize = "int_time")))] + pub int_time: u8, + /// GNSS signal for which acquisition was attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Acq frequency bin width + #[cfg_attr(feature = "serde", serde(rename(serialize = "bin_width")))] + pub bin_width: u16, + /// Timestamp of the job complete event + #[cfg_attr(feature = "serde", serde(rename(serialize = "timestamp")))] + pub timestamp: u32, + /// Time spent to search for sid.code + #[cfg_attr(feature = "serde", serde(rename(serialize = "time_spent")))] + pub time_spent: u32, + /// Doppler range lowest frequency + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_min")))] + pub cf_min: i32, + /// Doppler range highest frequency + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_max")))] + pub cf_max: i32, + /// Doppler value of detected peak. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: i32, + /// Codephase of detected peak. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: u32, + } + + impl WireFormat for AcqSvProfile { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.job_type) + + WireFormat::len(&self.status) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.int_time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.bin_width) + + WireFormat::len(&self.timestamp) + + WireFormat::len(&self.time_spent) + + WireFormat::len(&self.cf_min) + + WireFormat::len(&self.cf_max) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.cp) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.job_type, buf); + WireFormat::write(&self.status, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.int_time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.bin_width, buf); + WireFormat::write(&self.timestamp, buf); + WireFormat::write(&self.time_spent, buf); + WireFormat::write(&self.cf_min, buf); + WireFormat::write(&self.cf_max, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.cp, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + AcqSvProfile { + job_type: WireFormat::parse_unchecked(buf), + status: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + int_time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + bin_width: WireFormat::parse_unchecked(buf), + timestamp: WireFormat::parse_unchecked(buf), + time_spent: WireFormat::parse_unchecked(buf), + cf_min: WireFormat::parse_unchecked(buf), + cf_max: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct AcqSvProfileDep { - /// SV search job type (deep, fallback, etc) - #[cfg_attr(feature = "serde", serde(rename(serialize = "job_type")))] - pub job_type: u8, - /// Acquisition status 1 is Success, 0 is Failure - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: u8, - /// CN0 value. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u16, - /// Acquisition integration time - #[cfg_attr(feature = "serde", serde(rename(serialize = "int_time")))] - pub int_time: u8, - /// GNSS signal for which acquisition was attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Acq frequency bin width - #[cfg_attr(feature = "serde", serde(rename(serialize = "bin_width")))] - pub bin_width: u16, - /// Timestamp of the job complete event - #[cfg_attr(feature = "serde", serde(rename(serialize = "timestamp")))] - pub timestamp: u32, - /// Time spent to search for sid.code - #[cfg_attr(feature = "serde", serde(rename(serialize = "time_spent")))] - pub time_spent: u32, - /// Doppler range lowest frequency - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_min")))] - pub cf_min: i32, - /// Doppler range highest frequency - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_max")))] - pub cf_max: i32, - /// Doppler value of detected peak. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: i32, - /// Codephase of detected peak. Only valid if status is '1' - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: u32, -} - -impl WireFormat for AcqSvProfileDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.job_type) - + WireFormat::len(&self.status) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.int_time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.bin_width) - + WireFormat::len(&self.timestamp) - + WireFormat::len(&self.time_spent) - + WireFormat::len(&self.cf_min) - + WireFormat::len(&self.cf_max) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.cp) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.job_type, buf); - WireFormat::write(&self.status, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.int_time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.bin_width, buf); - WireFormat::write(&self.timestamp, buf); - WireFormat::write(&self.time_spent, buf); - WireFormat::write(&self.cf_min, buf); - WireFormat::write(&self.cf_max, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.cp, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - AcqSvProfileDep { - job_type: WireFormat::parse_unchecked(buf), - status: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - int_time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - bin_width: WireFormat::parse_unchecked(buf), - timestamp: WireFormat::parse_unchecked(buf), - time_spent: WireFormat::parse_unchecked(buf), - cf_min: WireFormat::parse_unchecked(buf), - cf_max: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), +pub mod acq_sv_profile_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct AcqSvProfileDep { + /// SV search job type (deep, fallback, etc) + #[cfg_attr(feature = "serde", serde(rename(serialize = "job_type")))] + pub job_type: u8, + /// Acquisition status 1 is Success, 0 is Failure + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: u8, + /// CN0 value. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u16, + /// Acquisition integration time + #[cfg_attr(feature = "serde", serde(rename(serialize = "int_time")))] + pub int_time: u8, + /// GNSS signal for which acquisition was attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Acq frequency bin width + #[cfg_attr(feature = "serde", serde(rename(serialize = "bin_width")))] + pub bin_width: u16, + /// Timestamp of the job complete event + #[cfg_attr(feature = "serde", serde(rename(serialize = "timestamp")))] + pub timestamp: u32, + /// Time spent to search for sid.code + #[cfg_attr(feature = "serde", serde(rename(serialize = "time_spent")))] + pub time_spent: u32, + /// Doppler range lowest frequency + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_min")))] + pub cf_min: i32, + /// Doppler range highest frequency + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf_max")))] + pub cf_max: i32, + /// Doppler value of detected peak. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: i32, + /// Codephase of detected peak. Only valid if status is '1' + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: u32, + } + + impl WireFormat for AcqSvProfileDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.job_type) + + WireFormat::len(&self.status) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.int_time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.bin_width) + + WireFormat::len(&self.timestamp) + + WireFormat::len(&self.time_spent) + + WireFormat::len(&self.cf_min) + + WireFormat::len(&self.cf_max) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.cp) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.job_type, buf); + WireFormat::write(&self.status, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.int_time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.bin_width, buf); + WireFormat::write(&self.timestamp, buf); + WireFormat::write(&self.time_spent, buf); + WireFormat::write(&self.cf_min, buf); + WireFormat::write(&self.cf_max, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.cp, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + AcqSvProfileDep { + job_type: WireFormat::parse_unchecked(buf), + status: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + int_time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + bin_width: WireFormat::parse_unchecked(buf), + timestamp: WireFormat::parse_unchecked(buf), + time_spent: WireFormat::parse_unchecked(buf), + cf_min: WireFormat::parse_unchecked(buf), + cf_max: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + } } } } -/// Satellite acquisition result -/// -/// This message describes the results from an attempted GPS signal -/// acquisition search for a satellite PRN over a code phase/carrier frequency -/// range. It contains the parameters of the point in the acquisition search -/// space with the best carrier-to-noise (CN/0) ratio. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqResult { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// CN/0 of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: f32, - /// Code phase of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: f32, - /// Carrier frequency of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: f32, - /// GNSS signal for which acquisition was attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, -} - -impl ConcreteMessage for MsgAcqResult { - const MESSAGE_TYPE: u16 = 47; - const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT"; -} - -impl SbpMessage for MsgAcqResult { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_acq_result { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite acquisition result + /// + /// This message describes the results from an attempted GPS signal + /// acquisition search for a satellite PRN over a code phase/carrier frequency + /// range. It contains the parameters of the point in the acquisition search + /// space with the best carrier-to-noise (CN/0) ratio. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqResult { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// CN/0 of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: f32, + /// Code phase of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: f32, + /// Carrier frequency of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: f32, + /// GNSS signal for which acquisition was attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + } + + impl ConcreteMessage for MsgAcqResult { + const MESSAGE_TYPE: u16 = 47; + const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT"; + } + + impl SbpMessage for MsgAcqResult { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgAcqResult { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqResult(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgAcqResult { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqResult(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgAcqResult { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.cn0) - + WireFormat::len(&self.cp) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.cp, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqResult { - sender_id: None, - cn0: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgAcqResult { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.cn0) + + WireFormat::len(&self.cp) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.cp, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqResult { + sender_id: None, + cn0: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqResultDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// SNR of best point. Currently dimensionless, but will have units of dB Hz - /// in the revision of this message. - #[cfg_attr(feature = "serde", serde(rename(serialize = "snr")))] - pub snr: f32, - /// Code phase of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: f32, - /// Carrier frequency of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: f32, - /// PRN-1 identifier of the satellite signal for which acquisition was - /// attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, -} - -impl ConcreteMessage for MsgAcqResultDepA { - const MESSAGE_TYPE: u16 = 21; - const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_A"; -} - -impl SbpMessage for MsgAcqResultDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_acq_result_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqResultDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// SNR of best point. Currently dimensionless, but will have units of dB Hz + /// in the revision of this message. + #[cfg_attr(feature = "serde", serde(rename(serialize = "snr")))] + pub snr: f32, + /// Code phase of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: f32, + /// Carrier frequency of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: f32, + /// PRN-1 identifier of the satellite signal for which acquisition was + /// attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + } + + impl ConcreteMessage for MsgAcqResultDepA { + const MESSAGE_TYPE: u16 = 21; + const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_A"; + } + + impl SbpMessage for MsgAcqResultDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgAcqResultDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqResultDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgAcqResultDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqResultDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgAcqResultDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.snr) - + WireFormat::len(&self.cp) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.prn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.snr, buf); - WireFormat::write(&self.cp, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.prn, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqResultDepA { - sender_id: None, - snr: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgAcqResultDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.snr) + + WireFormat::len(&self.cp) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.prn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.snr, buf); + WireFormat::write(&self.cp, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.prn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqResultDepA { + sender_id: None, + snr: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqResultDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// SNR of best point. Currently in arbitrary SNR points, but will be in - /// units of dB Hz in a later revision of this message. - #[cfg_attr(feature = "serde", serde(rename(serialize = "snr")))] - pub snr: f32, - /// Code phase of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: f32, - /// Carrier frequency of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: f32, - /// GNSS signal for which acquisition was attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, -} - -impl ConcreteMessage for MsgAcqResultDepB { - const MESSAGE_TYPE: u16 = 20; - const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_B"; -} - -impl SbpMessage for MsgAcqResultDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_acq_result_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqResultDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// SNR of best point. Currently in arbitrary SNR points, but will be in + /// units of dB Hz in a later revision of this message. + #[cfg_attr(feature = "serde", serde(rename(serialize = "snr")))] + pub snr: f32, + /// Code phase of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: f32, + /// Carrier frequency of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: f32, + /// GNSS signal for which acquisition was attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + } + + impl ConcreteMessage for MsgAcqResultDepB { + const MESSAGE_TYPE: u16 = 20; + const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_B"; + } + + impl SbpMessage for MsgAcqResultDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgAcqResultDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqResultDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgAcqResultDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqResultDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgAcqResultDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.snr) - + WireFormat::len(&self.cp) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.snr, buf); - WireFormat::write(&self.cp, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqResultDepB { - sender_id: None, - snr: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgAcqResultDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.snr) + + WireFormat::len(&self.cp) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.snr, buf); + WireFormat::write(&self.cp, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqResultDepB { + sender_id: None, + snr: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqResultDepC { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// CN/0 of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: f32, - /// Code phase of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] - pub cp: f32, - /// Carrier frequency of best point - #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] - pub cf: f32, - /// GNSS signal for which acquisition was attempted - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, -} - -impl ConcreteMessage for MsgAcqResultDepC { - const MESSAGE_TYPE: u16 = 31; - const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_C"; -} - -impl SbpMessage for MsgAcqResultDepC { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_acq_result_dep_c { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqResultDepC { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// CN/0 of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: f32, + /// Code phase of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cp")))] + pub cp: f32, + /// Carrier frequency of best point + #[cfg_attr(feature = "serde", serde(rename(serialize = "cf")))] + pub cf: f32, + /// GNSS signal for which acquisition was attempted + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + } + + impl ConcreteMessage for MsgAcqResultDepC { + const MESSAGE_TYPE: u16 = 31; + const MESSAGE_NAME: &'static str = "MSG_ACQ_RESULT_DEP_C"; + } + + impl SbpMessage for MsgAcqResultDepC { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgAcqResultDepC { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqResultDepC(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgAcqResultDepC { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqResultDepC(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgAcqResultDepC { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.cn0) - + WireFormat::len(&self.cp) - + WireFormat::len(&self.cf) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.cp, buf); - WireFormat::write(&self.cf, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqResultDepC { - sender_id: None, - cn0: WireFormat::parse_unchecked(buf), - cp: WireFormat::parse_unchecked(buf), - cf: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgAcqResultDepC { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.cn0) + + WireFormat::len(&self.cp) + + WireFormat::len(&self.cf) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.cp, buf); + WireFormat::write(&self.cf, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqResultDepC { + sender_id: None, + cn0: WireFormat::parse_unchecked(buf), + cp: WireFormat::parse_unchecked(buf), + cf: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } } } } -/// Acquisition perfomance measurement and debug -/// -/// The message describes all SV profiles during acquisition time. The message -/// is used to debug and measure the performance. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqSvProfile { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// SV profiles during acquisition time - #[cfg_attr(feature = "serde", serde(rename(serialize = "acq_sv_profile")))] - pub acq_sv_profile: Vec, -} +pub mod msg_acq_sv_profile { + #![allow(unused_imports)] -impl ConcreteMessage for MsgAcqSvProfile { - const MESSAGE_TYPE: u16 = 46; - const MESSAGE_NAME: &'static str = "MSG_ACQ_SV_PROFILE"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgAcqSvProfile { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Acquisition perfomance measurement and debug + /// + /// The message describes all SV profiles during acquisition time. The message + /// is used to debug and measure the performance. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqSvProfile { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// SV profiles during acquisition time + #[cfg_attr(feature = "serde", serde(rename(serialize = "acq_sv_profile")))] + pub acq_sv_profile: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgAcqSvProfile { + const MESSAGE_TYPE: u16 = 46; + const MESSAGE_NAME: &'static str = "MSG_ACQ_SV_PROFILE"; } -} -impl TryFrom for MsgAcqSvProfile { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqSvProfile(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgAcqSvProfile { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgAcqSvProfile { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.acq_sv_profile) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.acq_sv_profile, buf); + impl TryFrom for MsgAcqSvProfile { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqSvProfile(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqSvProfile { - sender_id: None, - acq_sv_profile: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgAcqSvProfile { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.acq_sv_profile) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.acq_sv_profile, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqSvProfile { + sender_id: None, + acq_sv_profile: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAcqSvProfileDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// SV profiles during acquisition time - #[cfg_attr(feature = "serde", serde(rename(serialize = "acq_sv_profile")))] - pub acq_sv_profile: Vec, -} +pub mod msg_acq_sv_profile_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgAcqSvProfileDep { - const MESSAGE_TYPE: u16 = 30; - const MESSAGE_NAME: &'static str = "MSG_ACQ_SV_PROFILE_DEP"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgAcqSvProfileDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAcqSvProfileDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// SV profiles during acquisition time + #[cfg_attr(feature = "serde", serde(rename(serialize = "acq_sv_profile")))] + pub acq_sv_profile: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgAcqSvProfileDep { + const MESSAGE_TYPE: u16 = 30; + const MESSAGE_NAME: &'static str = "MSG_ACQ_SV_PROFILE_DEP"; } -} -impl TryFrom for MsgAcqSvProfileDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAcqSvProfileDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgAcqSvProfileDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgAcqSvProfileDep { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.acq_sv_profile) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.acq_sv_profile, buf); + impl TryFrom for MsgAcqSvProfileDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAcqSvProfileDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAcqSvProfileDep { - sender_id: None, - acq_sv_profile: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgAcqSvProfileDep { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.acq_sv_profile) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.acq_sv_profile, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAcqSvProfileDep { + sender_id: None, + acq_sv_profile: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/bootload.rs b/rust/sbp/src/messages/bootload.rs index 68e185808d..6d91a7d0da 100644 --- a/rust/sbp/src/messages/bootload.rs +++ b/rust/sbp/src/messages/bootload.rs @@ -17,394 +17,482 @@ //! //! Note that some of these messages share the same message type ID for both //! the host request and the device response. - -use super::lib::*; - -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBootloaderHandshakeDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Version number string (not NULL terminated) - #[cfg_attr(feature = "serde", serde(rename(serialize = "handshake")))] - pub handshake: Vec, -} - -impl ConcreteMessage for MsgBootloaderHandshakeDepA { - const MESSAGE_TYPE: u16 = 176; - const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_DEP_A"; -} - -impl SbpMessage for MsgBootloaderHandshakeDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub use msg_bootloader_handshake_dep_a::MsgBootloaderHandshakeDepA; +pub use msg_bootloader_handshake_req::MsgBootloaderHandshakeReq; +pub use msg_bootloader_handshake_resp::MsgBootloaderHandshakeResp; +pub use msg_bootloader_jump_to_app::MsgBootloaderJumpToApp; +pub use msg_nap_device_dna_req::MsgNapDeviceDnaReq; +pub use msg_nap_device_dna_resp::MsgNapDeviceDnaResp; + +pub mod msg_bootloader_handshake_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBootloaderHandshakeDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Version number string (not NULL terminated) + #[cfg_attr(feature = "serde", serde(rename(serialize = "handshake")))] + pub handshake: Vec, + } + + impl ConcreteMessage for MsgBootloaderHandshakeDepA { + const MESSAGE_TYPE: u16 = 176; + const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_DEP_A"; + } + + impl SbpMessage for MsgBootloaderHandshakeDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgBootloaderHandshakeDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBootloaderHandshakeDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgBootloaderHandshakeDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBootloaderHandshakeDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgBootloaderHandshakeDepA { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.handshake) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.handshake, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBootloaderHandshakeDepA { - sender_id: None, - handshake: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgBootloaderHandshakeDepA { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.handshake) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.handshake, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBootloaderHandshakeDepA { + sender_id: None, + handshake: WireFormat::parse_unchecked(buf), + } } } } -/// Bootloading handshake request (host => device) -/// -/// The handshake message request from the host establishes a handshake -/// between the device bootloader and the host. The response from the device -/// is MSG_BOOTLOADER_HANDSHAKE_RESP. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBootloaderHandshakeReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_bootloader_handshake_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgBootloaderHandshakeReq { - const MESSAGE_TYPE: u16 = 179; - const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_REQ"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgBootloaderHandshakeReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Bootloading handshake request (host => device) + /// + /// The handshake message request from the host establishes a handshake + /// between the device bootloader and the host. The response from the device + /// is MSG_BOOTLOADER_HANDSHAKE_RESP. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBootloaderHandshakeReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgBootloaderHandshakeReq { + const MESSAGE_TYPE: u16 = 179; + const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_REQ"; } -} -impl TryFrom for MsgBootloaderHandshakeReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBootloaderHandshakeReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgBootloaderHandshakeReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgBootloaderHandshakeReq { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgBootloaderHandshakeReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBootloaderHandshakeReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgBootloaderHandshakeReq { sender_id: None } + + impl WireFormat for MsgBootloaderHandshakeReq { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgBootloaderHandshakeReq { sender_id: None } + } } } -/// Bootloading handshake response (host <= device) -/// -/// The handshake message response from the device establishes a handshake -/// between the device bootloader and the host. The request from the host is -/// MSG_BOOTLOADER_HANDSHAKE_REQ. The payload contains the bootloader version -/// number and the SBP protocol version number. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBootloaderHandshakeResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Bootloader flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, - /// Bootloader version number - #[cfg_attr(feature = "serde", serde(rename(serialize = "version")))] - pub version: SbpString, Unterminated>, -} +pub mod msg_bootloader_handshake_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Bootloading handshake response (host <= device) + /// + /// The handshake message response from the device establishes a handshake + /// between the device bootloader and the host. The request from the host is + /// MSG_BOOTLOADER_HANDSHAKE_REQ. The payload contains the bootloader version + /// number and the SBP protocol version number. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBootloaderHandshakeResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Bootloader flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + /// Bootloader version number + #[cfg_attr(feature = "serde", serde(rename(serialize = "version")))] + pub version: SbpString, Unterminated>, + } + + impl MsgBootloaderHandshakeResp { + /// Gets the `sbp_major_protocol_version_number` stored in `flags`. + pub fn sbp_major_protocol_version_number(&self) -> u8 { + get_bit_range!(self.flags, u32, u8, 15, 8) + } -impl ConcreteMessage for MsgBootloaderHandshakeResp { - const MESSAGE_TYPE: u16 = 180; - const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_RESP"; -} + /// Sets the `sbp_major_protocol_version_number` bitrange of `flags`. + pub fn set_sbp_major_protocol_version_number( + &mut self, + sbp_major_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.flags, + sbp_major_protocol_version_number, + u32, + u8, + 15, + 8 + ); + } -impl SbpMessage for MsgBootloaderHandshakeResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Gets the `sbp_minor_protocol_version_number` stored in `flags`. + pub fn sbp_minor_protocol_version_number(&self) -> u8 { + get_bit_range!(self.flags, u32, u8, 7, 0) + } + + /// Sets the `sbp_minor_protocol_version_number` bitrange of `flags`. + pub fn set_sbp_minor_protocol_version_number( + &mut self, + sbp_minor_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.flags, + sbp_minor_protocol_version_number, + u32, + u8, + 7, + 0 + ); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgBootloaderHandshakeResp { + const MESSAGE_TYPE: u16 = 180; + const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_HANDSHAKE_RESP"; } -} -impl TryFrom for MsgBootloaderHandshakeResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBootloaderHandshakeResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgBootloaderHandshakeResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgBootloaderHandshakeResp { - const MIN_LEN: usize = - ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) + WireFormat::len(&self.version) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.version, buf); + impl TryFrom for MsgBootloaderHandshakeResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBootloaderHandshakeResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBootloaderHandshakeResp { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), - version: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgBootloaderHandshakeResp { + const MIN_LEN: usize = ::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + WireFormat::len(&self.version) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.version, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBootloaderHandshakeResp { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + version: WireFormat::parse_unchecked(buf), + } } } } -/// Bootloader jump to application (host => device) -/// -/// The host initiates the bootloader to jump to the application. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBootloaderJumpToApp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Ignored by the device - #[cfg_attr(feature = "serde", serde(rename(serialize = "jump")))] - pub jump: u8, -} +pub mod msg_bootloader_jump_to_app { + #![allow(unused_imports)] -impl ConcreteMessage for MsgBootloaderJumpToApp { - const MESSAGE_TYPE: u16 = 177; - const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_JUMP_TO_APP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgBootloaderJumpToApp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Bootloader jump to application (host => device) + /// + /// The host initiates the bootloader to jump to the application. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBootloaderJumpToApp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Ignored by the device + #[cfg_attr(feature = "serde", serde(rename(serialize = "jump")))] + pub jump: u8, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgBootloaderJumpToApp { + const MESSAGE_TYPE: u16 = 177; + const MESSAGE_NAME: &'static str = "MSG_BOOTLOADER_JUMP_TO_APP"; } -} -impl TryFrom for MsgBootloaderJumpToApp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBootloaderJumpToApp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgBootloaderJumpToApp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgBootloaderJumpToApp { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.jump) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.jump, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBootloaderJumpToApp { - sender_id: None, - jump: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgBootloaderJumpToApp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBootloaderJumpToApp(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Read FPGA device ID over UART request (host => device) -/// -/// The device message from the host reads a unique device identifier from the -/// SwiftNAP, an FPGA. The host requests the ID by sending a -/// MSG_NAP_DEVICE_DNA_REQ message. The device responds with a -/// MSG_NAP_DEVICE_DNA_RESP message with the device ID in the payload. Note -/// that this ID is tied to the FPGA, and not related to the Piksi's serial -/// number. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNapDeviceDnaReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} - -impl ConcreteMessage for MsgNapDeviceDnaReq { - const MESSAGE_TYPE: u16 = 222; - const MESSAGE_NAME: &'static str = "MSG_NAP_DEVICE_DNA_REQ"; -} -impl SbpMessage for MsgNapDeviceDnaReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgBootloaderJumpToApp { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.jump) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.jump, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBootloaderJumpToApp { + sender_id: None, + jump: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgNapDeviceDnaReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNapDeviceDnaReq(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_nap_device_dna_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Read FPGA device ID over UART request (host => device) + /// + /// The device message from the host reads a unique device identifier from the + /// SwiftNAP, an FPGA. The host requests the ID by sending a + /// MSG_NAP_DEVICE_DNA_REQ message. The device responds with a + /// MSG_NAP_DEVICE_DNA_RESP message with the device ID in the payload. Note + /// that this ID is tied to the FPGA, and not related to the Piksi's serial + /// number. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNapDeviceDnaReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + } + + impl ConcreteMessage for MsgNapDeviceDnaReq { + const MESSAGE_TYPE: u16 = 222; + const MESSAGE_NAME: &'static str = "MSG_NAP_DEVICE_DNA_REQ"; + } + + impl SbpMessage for MsgNapDeviceDnaReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgNapDeviceDnaReq { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 - } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgNapDeviceDnaReq { sender_id: None } + impl TryFrom for MsgNapDeviceDnaReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNapDeviceDnaReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} - -/// Read FPGA device ID over UART response (host <= device) -/// -/// The device message from the host reads a unique device identifier from the -/// SwiftNAP, an FPGA. The host requests the ID by sending a -/// MSG_NAP_DEVICE_DNA_REQ message. The device responds with a -/// MSG_NAP_DEVICE_DNA_RESP message with the device ID in the payload. Note -/// that this ID is tied to the FPGA, and not related to the Piksi's serial -/// number. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNapDeviceDnaResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// 57-bit SwiftNAP FPGA Device ID. Remaining bits are padded on the right. - #[cfg_attr(feature = "serde", serde(rename(serialize = "dna")))] - pub dna: [u8; 8], -} -impl ConcreteMessage for MsgNapDeviceDnaResp { - const MESSAGE_TYPE: u16 = 221; - const MESSAGE_NAME: &'static str = "MSG_NAP_DEVICE_DNA_RESP"; -} - -impl SbpMessage for MsgNapDeviceDnaResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgNapDeviceDnaReq { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgNapDeviceDnaReq { sender_id: None } + } } } -impl TryFrom for MsgNapDeviceDnaResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNapDeviceDnaResp(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_nap_device_dna_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Read FPGA device ID over UART response (host <= device) + /// + /// The device message from the host reads a unique device identifier from the + /// SwiftNAP, an FPGA. The host requests the ID by sending a + /// MSG_NAP_DEVICE_DNA_REQ message. The device responds with a + /// MSG_NAP_DEVICE_DNA_RESP message with the device ID in the payload. Note + /// that this ID is tied to the FPGA, and not related to the Piksi's serial + /// number. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNapDeviceDnaResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// 57-bit SwiftNAP FPGA Device ID. Remaining bits are padded on the right. + #[cfg_attr(feature = "serde", serde(rename(serialize = "dna")))] + pub dna: [u8; 8], + } + + impl ConcreteMessage for MsgNapDeviceDnaResp { + const MESSAGE_TYPE: u16 = 221; + const MESSAGE_NAME: &'static str = "MSG_NAP_DEVICE_DNA_RESP"; + } + + impl SbpMessage for MsgNapDeviceDnaResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgNapDeviceDnaResp { - const MIN_LEN: usize = <[u8; 8] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.dna) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.dna, buf); + impl TryFrom for MsgNapDeviceDnaResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNapDeviceDnaResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgNapDeviceDnaResp { - sender_id: None, - dna: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgNapDeviceDnaResp { + const MIN_LEN: usize = <[u8; 8] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.dna) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.dna, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgNapDeviceDnaResp { + sender_id: None, + dna: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/ext_events.rs b/rust/sbp/src/messages/ext_events.rs index 7d74c4a9d0..a1647aeba7 100644 --- a/rust/sbp/src/messages/ext_events.rs +++ b/rust/sbp/src/messages/ext_events.rs @@ -14,113 +14,211 @@ //****************************************************************************/ //! Messages reporting accurately-timestamped external events, e.g. camera //! shutter time. +pub use msg_ext_event::MsgExtEvent; -use super::lib::*; - -/// Reports timestamped external pin event -/// -/// Reports detection of an external event, the GPS time it occurred, which -/// pin it was and whether it was rising or falling. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgExtEvent { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to - /// 500000) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] - pub ns_residual: i32, - /// Flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// Pin number. 0..9 = DEBUG0..9. - #[cfg_attr(feature = "serde", serde(rename(serialize = "pin")))] - pub pin: u8, -} +pub mod msg_ext_event { + #![allow(unused_imports)] -impl ConcreteMessage for MsgExtEvent { - const MESSAGE_TYPE: u16 = 257; - const MESSAGE_NAME: &'static str = "MSG_EXT_EVENT"; -} + use super::*; + use crate::messages::lib::*; + + /// Reports timestamped external pin event + /// + /// Reports detection of an external event, the GPS time it occurred, which + /// pin it was and whether it was rising or falling. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgExtEvent { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to + /// 500000) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] + pub ns_residual: i32, + /// Flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// Pin number. 0..9 = DEBUG0..9. + #[cfg_attr(feature = "serde", serde(rename(serialize = "pin")))] + pub pin: u8, + } + + impl MsgExtEvent { + /// Gets the [TimeQuality][self::TimeQuality] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeQuality` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeQuality` were added. + pub fn time_quality(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 1).try_into() + } + + /// Set the bitrange corresponding to the [TimeQuality][TimeQuality] of the `flags` bitfield. + pub fn set_time_quality(&mut self, time_quality: TimeQuality) { + set_bit_range!(&mut self.flags, time_quality, u8, u8, 1, 1); + } + + /// Gets the [NewLevelOfPin][self::NewLevelOfPin] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `NewLevelOfPin` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `NewLevelOfPin` were added. + pub fn new_level_of_pin(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 0, 0).try_into() + } -impl SbpMessage for MsgExtEvent { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Set the bitrange corresponding to the [NewLevelOfPin][NewLevelOfPin] of the `flags` bitfield. + pub fn set_new_level_of_pin(&mut self, new_level_of_pin: NewLevelOfPin) { + set_bit_range!(&mut self.flags, new_level_of_pin, u8, u8, 0, 0); + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgExtEvent { + const MESSAGE_TYPE: u16 = 257; + const MESSAGE_NAME: &'static str = "MSG_EXT_EVENT"; + } + + impl SbpMessage for MsgExtEvent { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + #[allow(clippy::useless_conversion)] + let wn: i16 = match self.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MsgExtEvent { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgExtEvent(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl WireFormat for MsgExtEvent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.wn) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.ns_residual) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.pin) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.wn, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.ns_residual, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.pin, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgExtEvent { + sender_id: None, + wn: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + ns_residual: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + pin: WireFormat::parse_unchecked(buf), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Time quality + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeQuality { + /// Unknown - don't have nav solution + UnknownDontHaveNavSolution = 0, + + /// Good (< 1 microsecond) + Good = 1, } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - #[allow(clippy::useless_conversion)] - let wn: i16 = match self.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl std::fmt::Display for TimeQuality { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeQuality::UnknownDontHaveNavSolution => { + f.write_str("Unknown - don't have nav solution") + } + TimeQuality::Good => f.write_str("Good (< 1 microsecond)"), + } + } } -} -impl TryFrom for MsgExtEvent { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgExtEvent(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for TimeQuality { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeQuality::UnknownDontHaveNavSolution), + 1 => Ok(TimeQuality::Good), + i => Err(i), + } } } -} -impl WireFormat for MsgExtEvent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.wn) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.ns_residual) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.pin) + /// New level of pin + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum NewLevelOfPin { + /// Low (falling edge) + Low = 0, + + /// High (rising edge) + High = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.wn, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.ns_residual, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.pin, buf); + + impl std::fmt::Display for NewLevelOfPin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + NewLevelOfPin::Low => f.write_str("Low (falling edge)"), + NewLevelOfPin::High => f.write_str("High (rising edge)"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgExtEvent { - sender_id: None, - wn: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - ns_residual: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - pin: WireFormat::parse_unchecked(buf), + + impl TryFrom for NewLevelOfPin { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(NewLevelOfPin::Low), + 1 => Ok(NewLevelOfPin::High), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/file_io.rs b/rust/sbp/src/messages/file_io.rs index 6f5e4cda5a..35825bea3e 100644 --- a/rust/sbp/src/messages/file_io.rs +++ b/rust/sbp/src/messages/file_io.rs @@ -20,708 +20,778 @@ //! //! Note that some of these messages share the same message type ID for both //! the host request and the device response. - -use super::lib::*; - -/// Request advice on the optimal configuration for FileIO -/// -/// Requests advice on the optimal configuration for a FileIO transfer. Newer -/// version of FileIO can support greater throughput by supporting a large -/// window of FileIO data that can be in-flight during read or write -/// operations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioConfigReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Advice sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, -} - -impl ConcreteMessage for MsgFileioConfigReq { - const MESSAGE_TYPE: u16 = 4097; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_CONFIG_REQ"; -} - -impl SbpMessage for MsgFileioConfigReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub use msg_fileio_config_req::MsgFileioConfigReq; +pub use msg_fileio_config_resp::MsgFileioConfigResp; +pub use msg_fileio_read_dir_req::MsgFileioReadDirReq; +pub use msg_fileio_read_dir_resp::MsgFileioReadDirResp; +pub use msg_fileio_read_req::MsgFileioReadReq; +pub use msg_fileio_read_resp::MsgFileioReadResp; +pub use msg_fileio_remove::MsgFileioRemove; +pub use msg_fileio_write_req::MsgFileioWriteReq; +pub use msg_fileio_write_resp::MsgFileioWriteResp; + +pub mod msg_fileio_config_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Request advice on the optimal configuration for FileIO + /// + /// Requests advice on the optimal configuration for a FileIO transfer. Newer + /// version of FileIO can support greater throughput by supporting a large + /// window of FileIO data that can be in-flight during read or write + /// operations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioConfigReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Advice sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + } + + impl ConcreteMessage for MsgFileioConfigReq { + const MESSAGE_TYPE: u16 = 4097; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_CONFIG_REQ"; + } + + impl SbpMessage for MsgFileioConfigReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgFileioConfigReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioConfigReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgFileioConfigReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioConfigReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgFileioConfigReq { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioConfigReq { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgFileioConfigReq { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioConfigReq { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + } } } } -/// Response with advice on the optimal configuration for FileIO. - -/// -/// The advice on the optimal configuration for a FileIO transfer. Newer -/// version of FileIO can support greater throughput by supporting a large -/// window of FileIO data that can be in-flight during read or write -/// operations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioConfigResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Advice sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// The number of SBP packets in the data in-flight window - #[cfg_attr(feature = "serde", serde(rename(serialize = "window_size")))] - pub window_size: u32, - /// The number of SBP packets sent in one PDU - #[cfg_attr(feature = "serde", serde(rename(serialize = "batch_size")))] - pub batch_size: u32, - /// The version of FileIO that is supported - #[cfg_attr(feature = "serde", serde(rename(serialize = "fileio_version")))] - pub fileio_version: u32, -} - -impl ConcreteMessage for MsgFileioConfigResp { - const MESSAGE_TYPE: u16 = 4098; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_CONFIG_RESP"; -} - -impl SbpMessage for MsgFileioConfigResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_fileio_config_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Response with advice on the optimal configuration for FileIO. + + /// + /// The advice on the optimal configuration for a FileIO transfer. Newer + /// version of FileIO can support greater throughput by supporting a large + /// window of FileIO data that can be in-flight during read or write + /// operations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioConfigResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Advice sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// The number of SBP packets in the data in-flight window + #[cfg_attr(feature = "serde", serde(rename(serialize = "window_size")))] + pub window_size: u32, + /// The number of SBP packets sent in one PDU + #[cfg_attr(feature = "serde", serde(rename(serialize = "batch_size")))] + pub batch_size: u32, + /// The version of FileIO that is supported + #[cfg_attr(feature = "serde", serde(rename(serialize = "fileio_version")))] + pub fileio_version: u32, + } + + impl ConcreteMessage for MsgFileioConfigResp { + const MESSAGE_TYPE: u16 = 4098; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_CONFIG_RESP"; + } + + impl SbpMessage for MsgFileioConfigResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgFileioConfigResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioConfigResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgFileioConfigResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioConfigResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgFileioConfigResp { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - + WireFormat::len(&self.window_size) - + WireFormat::len(&self.batch_size) - + WireFormat::len(&self.fileio_version) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.window_size, buf); - WireFormat::write(&self.batch_size, buf); - WireFormat::write(&self.fileio_version, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioConfigResp { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - window_size: WireFormat::parse_unchecked(buf), - batch_size: WireFormat::parse_unchecked(buf), - fileio_version: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgFileioConfigResp { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + + WireFormat::len(&self.window_size) + + WireFormat::len(&self.batch_size) + + WireFormat::len(&self.fileio_version) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.window_size, buf); + WireFormat::write(&self.batch_size, buf); + WireFormat::write(&self.fileio_version, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioConfigResp { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + window_size: WireFormat::parse_unchecked(buf), + batch_size: WireFormat::parse_unchecked(buf), + fileio_version: WireFormat::parse_unchecked(buf), + } } } } -/// List files in a directory (host => device) -/// -/// The read directory message lists the files in a directory on the device's -/// onboard flash file system. The offset parameter can be used to skip the -/// first n elements of the file list. Returns a MSG_FILEIO_READ_DIR_RESP -/// message containing the directory listings as a NULL delimited list. The -/// listing is chunked over multiple SBP packets. The sequence number in the -/// request will be returned in the response. If message is invalid, a -/// followup MSG_PRINT message will print "Invalid fileio read message". A -/// device will only respond to this message when it is received from sender -/// ID 0x42. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioReadDirReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Read sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// The offset to skip the first n elements of the file list - #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] - pub offset: u32, - /// Name of the directory to list - #[cfg_attr(feature = "serde", serde(rename(serialize = "dirname")))] - pub dirname: SbpString, NullTerminated>, -} - -impl ConcreteMessage for MsgFileioReadDirReq { - const MESSAGE_TYPE: u16 = 169; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_DIR_REQ"; -} - -impl SbpMessage for MsgFileioReadDirReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_fileio_read_dir_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// List files in a directory (host => device) + /// + /// The read directory message lists the files in a directory on the device's + /// onboard flash file system. The offset parameter can be used to skip the + /// first n elements of the file list. Returns a MSG_FILEIO_READ_DIR_RESP + /// message containing the directory listings as a NULL delimited list. The + /// listing is chunked over multiple SBP packets. The sequence number in the + /// request will be returned in the response. If message is invalid, a + /// followup MSG_PRINT message will print "Invalid fileio read message". A + /// device will only respond to this message when it is received from sender + /// ID 0x42. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioReadDirReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Read sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// The offset to skip the first n elements of the file list + #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] + pub offset: u32, + /// Name of the directory to list + #[cfg_attr(feature = "serde", serde(rename(serialize = "dirname")))] + pub dirname: SbpString, NullTerminated>, + } + + impl ConcreteMessage for MsgFileioReadDirReq { + const MESSAGE_TYPE: u16 = 169; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_DIR_REQ"; + } + + impl SbpMessage for MsgFileioReadDirReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgFileioReadDirReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioReadDirReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgFileioReadDirReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioReadDirReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgFileioReadDirReq { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + , NullTerminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - + WireFormat::len(&self.offset) - + WireFormat::len(&self.dirname) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.offset, buf); - WireFormat::write(&self.dirname, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioReadDirReq { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - offset: WireFormat::parse_unchecked(buf), - dirname: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgFileioReadDirReq { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + , NullTerminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + + WireFormat::len(&self.offset) + + WireFormat::len(&self.dirname) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.offset, buf); + WireFormat::write(&self.dirname, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioReadDirReq { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + offset: WireFormat::parse_unchecked(buf), + dirname: WireFormat::parse_unchecked(buf), + } } } } -/// Files listed in a directory (host <= device) -/// -/// The read directory message lists the files in a directory on the device's -/// onboard flash file system. Message contains the directory listings as a -/// NULL delimited list. The listing is chunked over multiple SBP packets and -/// the end of the list is identified by an packet with no entries. The -/// sequence number in the response is preserved from the request. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioReadDirResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Read sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Contents of read directory - #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] - pub contents: Vec, -} +pub mod msg_fileio_read_dir_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFileioReadDirResp { - const MESSAGE_TYPE: u16 = 170; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_DIR_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFileioReadDirResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Files listed in a directory (host <= device) + /// + /// The read directory message lists the files in a directory on the device's + /// onboard flash file system. Message contains the directory listings as a + /// NULL delimited list. The listing is chunked over multiple SBP packets and + /// the end of the list is identified by an packet with no entries. The + /// sequence number in the response is preserved from the request. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioReadDirResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Read sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Contents of read directory + #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] + pub contents: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgFileioReadDirResp { + const MESSAGE_TYPE: u16 = 170; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_DIR_RESP"; } -} -impl TryFrom for MsgFileioReadDirResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioReadDirResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgFileioReadDirResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFileioReadDirResp { - const MIN_LEN: usize = ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) + WireFormat::len(&self.contents) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.contents, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioReadDirResp { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - contents: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgFileioReadDirResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioReadDirResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Read file from the file system (host => device) -/// -/// The file read message reads a certain length (up to 255 bytes) from a -/// given offset into a file, and returns the data in a MSG_FILEIO_READ_RESP -/// message where the message length field indicates how many bytes were -/// successfully read. The sequence number in the request will be returned in -/// the response. If the message is invalid, a followup MSG_PRINT message will -/// print "Invalid fileio read message". A device will only respond to this -/// message when it is received from sender ID 0x42. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioReadReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Read sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// File offset - #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] - pub offset: u32, - /// Chunk size to read - #[cfg_attr(feature = "serde", serde(rename(serialize = "chunk_size")))] - pub chunk_size: u8, - /// Name of the file to read from - #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] - pub filename: SbpString, NullTerminated>, -} -impl ConcreteMessage for MsgFileioReadReq { - const MESSAGE_TYPE: u16 = 168; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_REQ"; + impl WireFormat for MsgFileioReadDirResp { + const MIN_LEN: usize = ::MIN_LEN + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + WireFormat::len(&self.contents) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.contents, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioReadDirResp { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + contents: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgFileioReadReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_fileio_read_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Read file from the file system (host => device) + /// + /// The file read message reads a certain length (up to 255 bytes) from a + /// given offset into a file, and returns the data in a MSG_FILEIO_READ_RESP + /// message where the message length field indicates how many bytes were + /// successfully read. The sequence number in the request will be returned in + /// the response. If the message is invalid, a followup MSG_PRINT message will + /// print "Invalid fileio read message". A device will only respond to this + /// message when it is received from sender ID 0x42. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioReadReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Read sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// File offset + #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] + pub offset: u32, + /// Chunk size to read + #[cfg_attr(feature = "serde", serde(rename(serialize = "chunk_size")))] + pub chunk_size: u8, + /// Name of the file to read from + #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] + pub filename: SbpString, NullTerminated>, + } + + impl ConcreteMessage for MsgFileioReadReq { + const MESSAGE_TYPE: u16 = 168; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_REQ"; + } + + impl SbpMessage for MsgFileioReadReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgFileioReadReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioReadReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgFileioReadReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioReadReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgFileioReadReq { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + , NullTerminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - + WireFormat::len(&self.offset) - + WireFormat::len(&self.chunk_size) - + WireFormat::len(&self.filename) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.offset, buf); - WireFormat::write(&self.chunk_size, buf); - WireFormat::write(&self.filename, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioReadReq { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - offset: WireFormat::parse_unchecked(buf), - chunk_size: WireFormat::parse_unchecked(buf), - filename: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgFileioReadReq { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + , NullTerminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + + WireFormat::len(&self.offset) + + WireFormat::len(&self.chunk_size) + + WireFormat::len(&self.filename) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.offset, buf); + WireFormat::write(&self.chunk_size, buf); + WireFormat::write(&self.filename, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioReadReq { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + offset: WireFormat::parse_unchecked(buf), + chunk_size: WireFormat::parse_unchecked(buf), + filename: WireFormat::parse_unchecked(buf), + } } } } -/// File read from the file system (host <= device) -/// -/// The file read message reads a certain length (up to 255 bytes) from a -/// given offset into a file, and returns the data in a message where the -/// message length field indicates how many bytes were successfully read. The -/// sequence number in the response is preserved from the request. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioReadResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Read sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Contents of read file - #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] - pub contents: Vec, -} +pub mod msg_fileio_read_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFileioReadResp { - const MESSAGE_TYPE: u16 = 163; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFileioReadResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// File read from the file system (host <= device) + /// + /// The file read message reads a certain length (up to 255 bytes) from a + /// given offset into a file, and returns the data in a message where the + /// message length field indicates how many bytes were successfully read. The + /// sequence number in the response is preserved from the request. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioReadResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Read sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Contents of read file + #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] + pub contents: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgFileioReadResp { + const MESSAGE_TYPE: u16 = 163; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_READ_RESP"; } -} -impl TryFrom for MsgFileioReadResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioReadResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgFileioReadResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFileioReadResp { - const MIN_LEN: usize = ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) + WireFormat::len(&self.contents) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.contents, buf); + impl TryFrom for MsgFileioReadResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioReadResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioReadResp { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - contents: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgFileioReadResp { + const MIN_LEN: usize = ::MIN_LEN + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + WireFormat::len(&self.contents) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.contents, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioReadResp { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + contents: WireFormat::parse_unchecked(buf), + } } } } -/// Delete a file from the file system (host => device) -/// -/// The file remove message deletes a file from the file system. If the -/// message is invalid, a followup MSG_PRINT message will print "Invalid -/// fileio remove message". A device will only process this message when it is -/// received from sender ID 0x42. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioRemove { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Name of the file to delete - #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] - pub filename: SbpString, NullTerminated>, -} +pub mod msg_fileio_remove { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFileioRemove { - const MESSAGE_TYPE: u16 = 172; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_REMOVE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFileioRemove { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Delete a file from the file system (host => device) + /// + /// The file remove message deletes a file from the file system. If the + /// message is invalid, a followup MSG_PRINT message will print "Invalid + /// fileio remove message". A device will only process this message when it is + /// received from sender ID 0x42. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioRemove { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Name of the file to delete + #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] + pub filename: SbpString, NullTerminated>, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgFileioRemove { + const MESSAGE_TYPE: u16 = 172; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_REMOVE"; } -} -impl TryFrom for MsgFileioRemove { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioRemove(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgFileioRemove { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFileioRemove { - const MIN_LEN: usize = , NullTerminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.filename) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.filename, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioRemove { - sender_id: None, - filename: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgFileioRemove { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioRemove(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Write to file (host => device) -/// -/// The file write message writes a certain length (up to 255 bytes) of data -/// to a file at a given offset. Returns a copy of the original -/// MSG_FILEIO_WRITE_RESP message to check integrity of the write. The -/// sequence number in the request will be returned in the response. If -/// message is invalid, a followup MSG_PRINT message will print "Invalid -/// fileio write message". A device will only process this message when it is -/// received from sender ID 0x42. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioWriteReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Write sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Offset into the file at which to start writing in bytes - #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] - pub offset: u32, - /// Name of the file to write to - #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] - pub filename: SbpString, NullTerminated>, - /// Variable-length array of data to write - #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] - pub data: Vec, -} -impl ConcreteMessage for MsgFileioWriteReq { - const MESSAGE_TYPE: u16 = 173; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_WRITE_REQ"; + impl WireFormat for MsgFileioRemove { + const MIN_LEN: usize = , NullTerminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.filename) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.filename, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioRemove { + sender_id: None, + filename: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgFileioWriteReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_fileio_write_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Write to file (host => device) + /// + /// The file write message writes a certain length (up to 255 bytes) of data + /// to a file at a given offset. Returns a copy of the original + /// MSG_FILEIO_WRITE_RESP message to check integrity of the write. The + /// sequence number in the request will be returned in the response. If + /// message is invalid, a followup MSG_PRINT message will print "Invalid + /// fileio write message". A device will only process this message when it is + /// received from sender ID 0x42. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioWriteReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Write sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Offset into the file at which to start writing in bytes + #[cfg_attr(feature = "serde", serde(rename(serialize = "offset")))] + pub offset: u32, + /// Name of the file to write to + #[cfg_attr(feature = "serde", serde(rename(serialize = "filename")))] + pub filename: SbpString, NullTerminated>, + /// Variable-length array of data to write + #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] + pub data: Vec, + } + + impl ConcreteMessage for MsgFileioWriteReq { + const MESSAGE_TYPE: u16 = 173; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_WRITE_REQ"; + } + + impl SbpMessage for MsgFileioWriteReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgFileioWriteReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioWriteReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgFileioWriteReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioWriteReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgFileioWriteReq { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + , NullTerminated> as WireFormat>::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - + WireFormat::len(&self.offset) - + WireFormat::len(&self.filename) - + WireFormat::len(&self.data) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.offset, buf); - WireFormat::write(&self.filename, buf); - WireFormat::write(&self.data, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioWriteReq { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - offset: WireFormat::parse_unchecked(buf), - filename: WireFormat::parse_unchecked(buf), - data: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgFileioWriteReq { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + , NullTerminated> as WireFormat>::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + + WireFormat::len(&self.offset) + + WireFormat::len(&self.filename) + + WireFormat::len(&self.data) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.offset, buf); + WireFormat::write(&self.filename, buf); + WireFormat::write(&self.data, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioWriteReq { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + offset: WireFormat::parse_unchecked(buf), + filename: WireFormat::parse_unchecked(buf), + data: WireFormat::parse_unchecked(buf), + } } } } -/// File written to (host <= device) -/// -/// The file write message writes a certain length (up to 255 bytes) of data -/// to a file at a given offset. The message is a copy of the original -/// MSG_FILEIO_WRITE_REQ message to check integrity of the write. The sequence -/// number in the response is preserved from the request. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFileioWriteResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Write sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, -} +pub mod msg_fileio_write_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFileioWriteResp { - const MESSAGE_TYPE: u16 = 171; - const MESSAGE_NAME: &'static str = "MSG_FILEIO_WRITE_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFileioWriteResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// File written to (host <= device) + /// + /// The file write message writes a certain length (up to 255 bytes) of data + /// to a file at a given offset. The message is a copy of the original + /// MSG_FILEIO_WRITE_REQ message to check integrity of the write. The sequence + /// number in the response is preserved from the request. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFileioWriteResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Write sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgFileioWriteResp { + const MESSAGE_TYPE: u16 = 171; + const MESSAGE_NAME: &'static str = "MSG_FILEIO_WRITE_RESP"; } -} -impl TryFrom for MsgFileioWriteResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFileioWriteResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgFileioWriteResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFileioWriteResp { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); + impl TryFrom for MsgFileioWriteResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFileioWriteResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFileioWriteResp { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgFileioWriteResp { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFileioWriteResp { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/flash.rs b/rust/sbp/src/messages/flash.rs index 9964942066..021681519d 100644 --- a/rust/sbp/src/messages/flash.rs +++ b/rust/sbp/src/messages/flash.rs @@ -16,720 +16,1048 @@ //! these messages target specific flash memory peripherals used in Swift //! Navigation devices: the STM32 flash and the M25Pxx FPGA configuration //! flash from Piksi 2.3.1. This module does not apply to Piksi Multi. +pub use msg_flash_done::MsgFlashDone; +pub use msg_flash_erase::MsgFlashErase; +pub use msg_flash_program::MsgFlashProgram; +pub use msg_flash_read_req::MsgFlashReadReq; +pub use msg_flash_read_resp::MsgFlashReadResp; +pub use msg_m25_flash_write_status::MsgM25FlashWriteStatus; +pub use msg_stm_flash_lock_sector::MsgStmFlashLockSector; +pub use msg_stm_flash_unlock_sector::MsgStmFlashUnlockSector; +pub use msg_stm_unique_id_req::MsgStmUniqueIdReq; +pub use msg_stm_unique_id_resp::MsgStmUniqueIdResp; -use super::lib::*; - -/// Flash response message (host <= device) -/// -/// This message defines success or failure codes for a variety of flash -/// memory requests from the host to the device. Flash read and write -/// messages, such as MSG_FLASH_READ_REQ, or MSG_FLASH_PROGRAM, may return -/// this message on failure. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFlashDone { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Response flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "response")))] - pub response: u8, -} +pub mod msg_flash_done { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFlashDone { - const MESSAGE_TYPE: u16 = 224; - const MESSAGE_NAME: &'static str = "MSG_FLASH_DONE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFlashDone { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Flash response message (host <= device) + /// + /// This message defines success or failure codes for a variety of flash + /// memory requests from the host to the device. Flash read and write + /// messages, such as MSG_FLASH_READ_REQ, or MSG_FLASH_PROGRAM, may return + /// this message on failure. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFlashDone { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Response flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "response")))] + pub response: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgFlashDone { + /// Gets the [ResponseCode][self::ResponseCode] stored in the `response` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ResponseCode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ResponseCode` were added. + pub fn response_code(&self) -> Result { + get_bit_range!(self.response, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [ResponseCode][ResponseCode] of the `response` bitfield. + pub fn set_response_code(&mut self, response_code: ResponseCode) { + set_bit_range!(&mut self.response, response_code, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgFlashDone { + const MESSAGE_TYPE: u16 = 224; + const MESSAGE_NAME: &'static str = "MSG_FLASH_DONE"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgFlashDone { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgFlashDone { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFlashDone(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgFlashDone { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFlashDone(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgFlashDone { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.response) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.response, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFlashDone { + sender_id: None, + response: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgFlashDone { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.response) + /// Response code + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ResponseCode { + /// FLASH_OK + FlashOk = 0, + + /// FLASH_INVALID_FLASH + FlashInvalidFlash = 1, + + /// FLASH_INVALID_LEN + FlashInvalidLen = 2, + + /// FLASH_INVALID_ADDR + FlashInvalidAddr = 3, + + /// FLASH_INVALID_RANGE + FlashInvalidRange = 4, + + /// FLASH_INVALID_SECTOR + FlashInvalidSector = 5, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.response, buf); + + impl std::fmt::Display for ResponseCode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ResponseCode::FlashOk => f.write_str("FLASH_OK"), + ResponseCode::FlashInvalidFlash => f.write_str("FLASH_INVALID_FLASH"), + ResponseCode::FlashInvalidLen => f.write_str("FLASH_INVALID_LEN"), + ResponseCode::FlashInvalidAddr => f.write_str("FLASH_INVALID_ADDR"), + ResponseCode::FlashInvalidRange => f.write_str("FLASH_INVALID_RANGE"), + ResponseCode::FlashInvalidSector => f.write_str("FLASH_INVALID_SECTOR"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFlashDone { - sender_id: None, - response: WireFormat::parse_unchecked(buf), + + impl TryFrom for ResponseCode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ResponseCode::FlashOk), + 1 => Ok(ResponseCode::FlashInvalidFlash), + 2 => Ok(ResponseCode::FlashInvalidLen), + 3 => Ok(ResponseCode::FlashInvalidAddr), + 4 => Ok(ResponseCode::FlashInvalidRange), + 5 => Ok(ResponseCode::FlashInvalidSector), + i => Err(i), + } } } } -/// Erase sector of device flash memory (host => device) -/// -/// The flash erase message from the host erases a sector of either the STM or -/// M25 onboard flash memory. The device will reply with a MSG_FLASH_DONE -/// message containing the return code - FLASH_OK (0) on success or -/// FLASH_INVALID_FLASH (1) if the flash specified is invalid. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFlashErase { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Target flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] - pub target: u8, - /// Flash sector number to erase (0-11 for the STM, 0-15 for the M25) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sector_num")))] - pub sector_num: u32, -} +pub mod msg_flash_erase { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFlashErase { - const MESSAGE_TYPE: u16 = 226; - const MESSAGE_NAME: &'static str = "MSG_FLASH_ERASE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFlashErase { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Erase sector of device flash memory (host => device) + /// + /// The flash erase message from the host erases a sector of either the STM or + /// M25 onboard flash memory. The device will reply with a MSG_FLASH_DONE + /// message containing the return code - FLASH_OK (0) on success or + /// FLASH_INVALID_FLASH (1) if the flash specified is invalid. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFlashErase { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Target flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] + pub target: u8, + /// Flash sector number to erase (0-11 for the STM, 0-15 for the M25) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sector_num")))] + pub sector_num: u32, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgFlashErase { + /// Gets the [FlashTargetToRead][self::FlashTargetToRead] stored in the `target` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FlashTargetToRead` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FlashTargetToRead` were added. + pub fn flash_target_to_read(&self) -> Result { + get_bit_range!(self.target, u8, u8, 0, 0).try_into() + } + + /// Set the bitrange corresponding to the [FlashTargetToRead][FlashTargetToRead] of the `target` bitfield. + pub fn set_flash_target_to_read(&mut self, flash_target_to_read: FlashTargetToRead) { + set_bit_range!(&mut self.target, flash_target_to_read, u8, u8, 0, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgFlashErase { + const MESSAGE_TYPE: u16 = 226; + const MESSAGE_NAME: &'static str = "MSG_FLASH_ERASE"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgFlashErase { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgFlashErase { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFlashErase(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgFlashErase { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFlashErase(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgFlashErase { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.target) + WireFormat::len(&self.sector_num) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.target, buf); + WireFormat::write(&self.sector_num, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFlashErase { + sender_id: None, + target: WireFormat::parse_unchecked(buf), + sector_num: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgFlashErase { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.target) + WireFormat::len(&self.sector_num) + /// Flash target to read + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FlashTargetToRead { + /// FLASH_STM + FlashStm = 0, + + /// FLASH_M25 + FlashM25 = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.target, buf); - WireFormat::write(&self.sector_num, buf); + + impl std::fmt::Display for FlashTargetToRead { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FlashTargetToRead::FlashStm => f.write_str("FLASH_STM"), + FlashTargetToRead::FlashM25 => f.write_str("FLASH_M25"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFlashErase { - sender_id: None, - target: WireFormat::parse_unchecked(buf), - sector_num: WireFormat::parse_unchecked(buf), + + impl TryFrom for FlashTargetToRead { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FlashTargetToRead::FlashStm), + 1 => Ok(FlashTargetToRead::FlashM25), + i => Err(i), + } } } } -/// Program flash addresses -/// -/// The flash program message programs a set of addresses of either the STM or -/// M25 flash. The device replies with either a MSG_FLASH_DONE message -/// containing the return code FLASH_OK (0) on success, or FLASH_INVALID_LEN -/// (2) if the maximum write size is exceeded. Note that the sector-containing -/// addresses must be erased before addresses can be programmed. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFlashProgram { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Target flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] - pub target: u8, - /// Starting address offset to program - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] - pub addr_start: [u8; 3], - /// Length of set of addresses to program, counting up from starting address - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] - pub addr_len: u8, - /// Data to program addresses with, with length N=addr_len - #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] - pub data: Vec, -} +pub mod msg_flash_program { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFlashProgram { - const MESSAGE_TYPE: u16 = 230; - const MESSAGE_NAME: &'static str = "MSG_FLASH_PROGRAM"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFlashProgram { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Program flash addresses + /// + /// The flash program message programs a set of addresses of either the STM or + /// M25 flash. The device replies with either a MSG_FLASH_DONE message + /// containing the return code FLASH_OK (0) on success, or FLASH_INVALID_LEN + /// (2) if the maximum write size is exceeded. Note that the sector-containing + /// addresses must be erased before addresses can be programmed. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFlashProgram { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Target flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] + pub target: u8, + /// Starting address offset to program + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] + pub addr_start: [u8; 3], + /// Length of set of addresses to program, counting up from starting address + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] + pub addr_len: u8, + /// Data to program addresses with, with length N=addr_len + #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] + pub data: Vec, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgFlashProgram { + /// Gets the [FlashTargetToRead][self::FlashTargetToRead] stored in the `target` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FlashTargetToRead` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FlashTargetToRead` were added. + pub fn flash_target_to_read(&self) -> Result { + get_bit_range!(self.target, u8, u8, 0, 0).try_into() + } + + /// Set the bitrange corresponding to the [FlashTargetToRead][FlashTargetToRead] of the `target` bitfield. + pub fn set_flash_target_to_read(&mut self, flash_target_to_read: FlashTargetToRead) { + set_bit_range!(&mut self.target, flash_target_to_read, u8, u8, 0, 0); + } + } + + impl ConcreteMessage for MsgFlashProgram { + const MESSAGE_TYPE: u16 = 230; + const MESSAGE_NAME: &'static str = "MSG_FLASH_PROGRAM"; + } + + impl SbpMessage for MsgFlashProgram { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MsgFlashProgram { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFlashProgram(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl WireFormat for MsgFlashProgram { + const MIN_LEN: usize = ::MIN_LEN + + <[u8; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.target) + + WireFormat::len(&self.addr_start) + + WireFormat::len(&self.addr_len) + + WireFormat::len(&self.data) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.target, buf); + WireFormat::write(&self.addr_start, buf); + WireFormat::write(&self.addr_len, buf); + WireFormat::write(&self.data, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFlashProgram { + sender_id: None, + target: WireFormat::parse_unchecked(buf), + addr_start: WireFormat::parse_unchecked(buf), + addr_len: WireFormat::parse_unchecked(buf), + data: WireFormat::parse_unchecked(buf), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Flash target to read + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FlashTargetToRead { + /// FLASH_STM + FlashStm = 0, + + /// FLASH_M25 + FlashM25 = 1, } -} -impl TryFrom for MsgFlashProgram { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFlashProgram(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for FlashTargetToRead { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FlashTargetToRead::FlashStm => f.write_str("FLASH_STM"), + FlashTargetToRead::FlashM25 => f.write_str("FLASH_M25"), + } } } -} -impl WireFormat for MsgFlashProgram { - const MIN_LEN: usize = ::MIN_LEN - + <[u8; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.target) - + WireFormat::len(&self.addr_start) - + WireFormat::len(&self.addr_len) - + WireFormat::len(&self.data) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.target, buf); - WireFormat::write(&self.addr_start, buf); - WireFormat::write(&self.addr_len, buf); - WireFormat::write(&self.data, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFlashProgram { - sender_id: None, - target: WireFormat::parse_unchecked(buf), - addr_start: WireFormat::parse_unchecked(buf), - addr_len: WireFormat::parse_unchecked(buf), - data: WireFormat::parse_unchecked(buf), + impl TryFrom for FlashTargetToRead { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FlashTargetToRead::FlashStm), + 1 => Ok(FlashTargetToRead::FlashM25), + i => Err(i), + } } } } -/// Read STM or M25 flash address request (host => device) -/// -/// The flash read message reads a set of addresses of either the STM or M25 -/// onboard flash. The device replies with a MSG_FLASH_READ_RESP message -/// containing either the read data on success or a MSG_FLASH_DONE message -/// containing the return code FLASH_INVALID_LEN (2) if the maximum read size -/// is exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the -/// allowed range. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFlashReadReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Target flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] - pub target: u8, - /// Starting address offset to read from - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] - pub addr_start: [u8; 3], - /// Length of set of addresses to read, counting up from starting address - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] - pub addr_len: u8, -} +pub mod msg_flash_read_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFlashReadReq { - const MESSAGE_TYPE: u16 = 231; - const MESSAGE_NAME: &'static str = "MSG_FLASH_READ_REQ"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFlashReadReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Read STM or M25 flash address request (host => device) + /// + /// The flash read message reads a set of addresses of either the STM or M25 + /// onboard flash. The device replies with a MSG_FLASH_READ_RESP message + /// containing either the read data on success or a MSG_FLASH_DONE message + /// containing the return code FLASH_INVALID_LEN (2) if the maximum read size + /// is exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the + /// allowed range. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFlashReadReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Target flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] + pub target: u8, + /// Starting address offset to read from + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] + pub addr_start: [u8; 3], + /// Length of set of addresses to read, counting up from starting address + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] + pub addr_len: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgFlashReadReq { + /// Gets the [FlashTargetToRead][self::FlashTargetToRead] stored in the `target` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FlashTargetToRead` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FlashTargetToRead` were added. + pub fn flash_target_to_read(&self) -> Result { + get_bit_range!(self.target, u8, u8, 0, 0).try_into() + } + + /// Set the bitrange corresponding to the [FlashTargetToRead][FlashTargetToRead] of the `target` bitfield. + pub fn set_flash_target_to_read(&mut self, flash_target_to_read: FlashTargetToRead) { + set_bit_range!(&mut self.target, flash_target_to_read, u8, u8, 0, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgFlashReadReq { + const MESSAGE_TYPE: u16 = 231; + const MESSAGE_NAME: &'static str = "MSG_FLASH_READ_REQ"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgFlashReadReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgFlashReadReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFlashReadReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgFlashReadReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFlashReadReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgFlashReadReq { + const MIN_LEN: usize = ::MIN_LEN + + <[u8; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.target) + + WireFormat::len(&self.addr_start) + + WireFormat::len(&self.addr_len) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.target, buf); + WireFormat::write(&self.addr_start, buf); + WireFormat::write(&self.addr_len, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFlashReadReq { + sender_id: None, + target: WireFormat::parse_unchecked(buf), + addr_start: WireFormat::parse_unchecked(buf), + addr_len: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgFlashReadReq { - const MIN_LEN: usize = ::MIN_LEN - + <[u8; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.target) - + WireFormat::len(&self.addr_start) - + WireFormat::len(&self.addr_len) + /// Flash target to read + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FlashTargetToRead { + /// FLASH_STM + FlashStm = 0, + + /// FLASH_M25 + FlashM25 = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.target, buf); - WireFormat::write(&self.addr_start, buf); - WireFormat::write(&self.addr_len, buf); + + impl std::fmt::Display for FlashTargetToRead { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FlashTargetToRead::FlashStm => f.write_str("FLASH_STM"), + FlashTargetToRead::FlashM25 => f.write_str("FLASH_M25"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFlashReadReq { - sender_id: None, - target: WireFormat::parse_unchecked(buf), - addr_start: WireFormat::parse_unchecked(buf), - addr_len: WireFormat::parse_unchecked(buf), + + impl TryFrom for FlashTargetToRead { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FlashTargetToRead::FlashStm), + 1 => Ok(FlashTargetToRead::FlashM25), + i => Err(i), + } } } } -/// Read STM or M25 flash address response (host <= device) -/// -/// The flash read message reads a set of addresses of either the STM or M25 -/// onboard flash. The device replies with a MSG_FLASH_READ_RESP message -/// containing either the read data on success or a MSG_FLASH_DONE message -/// containing the return code FLASH_INVALID_LEN (2) if the maximum read size -/// is exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the -/// allowed range. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFlashReadResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Target flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] - pub target: u8, - /// Starting address offset to read from - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] - pub addr_start: [u8; 3], - /// Length of set of addresses to read, counting up from starting address - #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] - pub addr_len: u8, -} +pub mod msg_flash_read_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFlashReadResp { - const MESSAGE_TYPE: u16 = 225; - const MESSAGE_NAME: &'static str = "MSG_FLASH_READ_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFlashReadResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Read STM or M25 flash address response (host <= device) + /// + /// The flash read message reads a set of addresses of either the STM or M25 + /// onboard flash. The device replies with a MSG_FLASH_READ_RESP message + /// containing either the read data on success or a MSG_FLASH_DONE message + /// containing the return code FLASH_INVALID_LEN (2) if the maximum read size + /// is exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the + /// allowed range. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFlashReadResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Target flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "target")))] + pub target: u8, + /// Starting address offset to read from + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_start")))] + pub addr_start: [u8; 3], + /// Length of set of addresses to read, counting up from starting address + #[cfg_attr(feature = "serde", serde(rename(serialize = "addr_len")))] + pub addr_len: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgFlashReadResp { + /// Gets the [FlashTargetToRead][self::FlashTargetToRead] stored in the `target` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FlashTargetToRead` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FlashTargetToRead` were added. + pub fn flash_target_to_read(&self) -> Result { + get_bit_range!(self.target, u8, u8, 0, 0).try_into() + } + + /// Set the bitrange corresponding to the [FlashTargetToRead][FlashTargetToRead] of the `target` bitfield. + pub fn set_flash_target_to_read(&mut self, flash_target_to_read: FlashTargetToRead) { + set_bit_range!(&mut self.target, flash_target_to_read, u8, u8, 0, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgFlashReadResp { + const MESSAGE_TYPE: u16 = 225; + const MESSAGE_NAME: &'static str = "MSG_FLASH_READ_RESP"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgFlashReadResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgFlashReadResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFlashReadResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgFlashReadResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFlashReadResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgFlashReadResp { + const MIN_LEN: usize = ::MIN_LEN + + <[u8; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.target) + + WireFormat::len(&self.addr_start) + + WireFormat::len(&self.addr_len) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.target, buf); + WireFormat::write(&self.addr_start, buf); + WireFormat::write(&self.addr_len, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFlashReadResp { + sender_id: None, + target: WireFormat::parse_unchecked(buf), + addr_start: WireFormat::parse_unchecked(buf), + addr_len: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgFlashReadResp { - const MIN_LEN: usize = ::MIN_LEN - + <[u8; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.target) - + WireFormat::len(&self.addr_start) - + WireFormat::len(&self.addr_len) + /// Flash target to read + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FlashTargetToRead { + /// FLASH_STM + FlashStm = 0, + + /// FLASH_M25 + FlashM25 = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.target, buf); - WireFormat::write(&self.addr_start, buf); - WireFormat::write(&self.addr_len, buf); + + impl std::fmt::Display for FlashTargetToRead { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FlashTargetToRead::FlashStm => f.write_str("FLASH_STM"), + FlashTargetToRead::FlashM25 => f.write_str("FLASH_M25"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFlashReadResp { - sender_id: None, - target: WireFormat::parse_unchecked(buf), - addr_start: WireFormat::parse_unchecked(buf), - addr_len: WireFormat::parse_unchecked(buf), + + impl TryFrom for FlashTargetToRead { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FlashTargetToRead::FlashStm), + 1 => Ok(FlashTargetToRead::FlashM25), + i => Err(i), + } } } } -/// Write M25 flash status register (host => device) -/// -/// The flash status message writes to the 8-bit M25 flash status register. -/// The device replies with a MSG_FLASH_DONE message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgM25FlashWriteStatus { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Byte to write to the M25 flash status register - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: [u8; 1], -} +pub mod msg_m25_flash_write_status { + #![allow(unused_imports)] -impl ConcreteMessage for MsgM25FlashWriteStatus { - const MESSAGE_TYPE: u16 = 243; - const MESSAGE_NAME: &'static str = "MSG_M25_FLASH_WRITE_STATUS"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgM25FlashWriteStatus { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Write M25 flash status register (host => device) + /// + /// The flash status message writes to the 8-bit M25 flash status register. + /// The device replies with a MSG_FLASH_DONE message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgM25FlashWriteStatus { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Byte to write to the M25 flash status register + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: [u8; 1], } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgM25FlashWriteStatus { + const MESSAGE_TYPE: u16 = 243; + const MESSAGE_NAME: &'static str = "MSG_M25_FLASH_WRITE_STATUS"; } -} -impl TryFrom for MsgM25FlashWriteStatus { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgM25FlashWriteStatus(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgM25FlashWriteStatus { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgM25FlashWriteStatus { - const MIN_LEN: usize = <[u8; 1] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.status) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.status, buf); + impl TryFrom for MsgM25FlashWriteStatus { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgM25FlashWriteStatus(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgM25FlashWriteStatus { - sender_id: None, - status: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgM25FlashWriteStatus { + const MIN_LEN: usize = <[u8; 1] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.status) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.status, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgM25FlashWriteStatus { + sender_id: None, + status: WireFormat::parse_unchecked(buf), + } } } } -/// Lock sector of STM flash memory (host => device) -/// -/// The flash lock message locks a sector of the STM flash memory. The device -/// replies with a MSG_FLASH_DONE message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStmFlashLockSector { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Flash sector number to lock - #[cfg_attr(feature = "serde", serde(rename(serialize = "sector")))] - pub sector: u32, -} +pub mod msg_stm_flash_lock_sector { + #![allow(unused_imports)] -impl ConcreteMessage for MsgStmFlashLockSector { - const MESSAGE_TYPE: u16 = 227; - const MESSAGE_NAME: &'static str = "MSG_STM_FLASH_LOCK_SECTOR"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgStmFlashLockSector { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Lock sector of STM flash memory (host => device) + /// + /// The flash lock message locks a sector of the STM flash memory. The device + /// replies with a MSG_FLASH_DONE message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStmFlashLockSector { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Flash sector number to lock + #[cfg_attr(feature = "serde", serde(rename(serialize = "sector")))] + pub sector: u32, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgStmFlashLockSector { + const MESSAGE_TYPE: u16 = 227; + const MESSAGE_NAME: &'static str = "MSG_STM_FLASH_LOCK_SECTOR"; } -} -impl TryFrom for MsgStmFlashLockSector { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStmFlashLockSector(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgStmFlashLockSector { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgStmFlashLockSector { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sector) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sector, buf); + impl TryFrom for MsgStmFlashLockSector { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStmFlashLockSector(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgStmFlashLockSector { - sender_id: None, - sector: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgStmFlashLockSector { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sector) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sector, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgStmFlashLockSector { + sender_id: None, + sector: WireFormat::parse_unchecked(buf), + } } } } -/// Unlock sector of STM flash memory (host => device) -/// -/// The flash unlock message unlocks a sector of the STM flash memory. The -/// device replies with a MSG_FLASH_DONE message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStmFlashUnlockSector { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Flash sector number to unlock - #[cfg_attr(feature = "serde", serde(rename(serialize = "sector")))] - pub sector: u32, -} +pub mod msg_stm_flash_unlock_sector { + #![allow(unused_imports)] -impl ConcreteMessage for MsgStmFlashUnlockSector { - const MESSAGE_TYPE: u16 = 228; - const MESSAGE_NAME: &'static str = "MSG_STM_FLASH_UNLOCK_SECTOR"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgStmFlashUnlockSector { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Unlock sector of STM flash memory (host => device) + /// + /// The flash unlock message unlocks a sector of the STM flash memory. The + /// device replies with a MSG_FLASH_DONE message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStmFlashUnlockSector { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Flash sector number to unlock + #[cfg_attr(feature = "serde", serde(rename(serialize = "sector")))] + pub sector: u32, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgStmFlashUnlockSector { + const MESSAGE_TYPE: u16 = 228; + const MESSAGE_NAME: &'static str = "MSG_STM_FLASH_UNLOCK_SECTOR"; } -} -impl TryFrom for MsgStmFlashUnlockSector { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStmFlashUnlockSector(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgStmFlashUnlockSector { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgStmFlashUnlockSector { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sector) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sector, buf); + impl TryFrom for MsgStmFlashUnlockSector { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStmFlashUnlockSector(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgStmFlashUnlockSector { - sender_id: None, - sector: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgStmFlashUnlockSector { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sector) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sector, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgStmFlashUnlockSector { + sender_id: None, + sector: WireFormat::parse_unchecked(buf), + } } } } -/// Read device's hard-coded unique ID request (host => device) - -/// -/// This message reads the device's hard-coded unique ID. The host requests -/// the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a -/// MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStmUniqueIdReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_stm_unique_id_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgStmUniqueIdReq { - const MESSAGE_TYPE: u16 = 232; - const MESSAGE_NAME: &'static str = "MSG_STM_UNIQUE_ID_REQ"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgStmUniqueIdReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Read device's hard-coded unique ID request (host => device) + + /// + /// This message reads the device's hard-coded unique ID. The host requests + /// the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a + /// MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStmUniqueIdReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgStmUniqueIdReq { + const MESSAGE_TYPE: u16 = 232; + const MESSAGE_NAME: &'static str = "MSG_STM_UNIQUE_ID_REQ"; } -} -impl TryFrom for MsgStmUniqueIdReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStmUniqueIdReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgStmUniqueIdReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgStmUniqueIdReq { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgStmUniqueIdReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStmUniqueIdReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgStmUniqueIdReq { sender_id: None } + + impl WireFormat for MsgStmUniqueIdReq { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgStmUniqueIdReq { sender_id: None } + } } } -/// Read device's hard-coded unique ID response (host <= device) - -/// -/// This message reads the device's hard-coded unique ID. The host requests -/// the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a -/// MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStmUniqueIdResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Device unique ID - #[cfg_attr(feature = "serde", serde(rename(serialize = "stm_id")))] - pub stm_id: [u8; 12], -} +pub mod msg_stm_unique_id_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgStmUniqueIdResp { - const MESSAGE_TYPE: u16 = 229; - const MESSAGE_NAME: &'static str = "MSG_STM_UNIQUE_ID_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgStmUniqueIdResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Read device's hard-coded unique ID response (host <= device) + + /// + /// This message reads the device's hard-coded unique ID. The host requests + /// the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a + /// MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStmUniqueIdResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Device unique ID + #[cfg_attr(feature = "serde", serde(rename(serialize = "stm_id")))] + pub stm_id: [u8; 12], } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgStmUniqueIdResp { + const MESSAGE_TYPE: u16 = 229; + const MESSAGE_NAME: &'static str = "MSG_STM_UNIQUE_ID_RESP"; } -} -impl TryFrom for MsgStmUniqueIdResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStmUniqueIdResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgStmUniqueIdResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgStmUniqueIdResp { - const MIN_LEN: usize = <[u8; 12] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.stm_id) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.stm_id, buf); + impl TryFrom for MsgStmUniqueIdResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStmUniqueIdResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgStmUniqueIdResp { - sender_id: None, - stm_id: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgStmUniqueIdResp { + const MIN_LEN: usize = <[u8; 12] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.stm_id) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.stm_id, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgStmUniqueIdResp { + sender_id: None, + stm_id: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/gnss.rs b/rust/sbp/src/messages/gnss.rs index bc5954e35b..6ffc561345 100644 --- a/rust/sbp/src/messages/gnss.rs +++ b/rust/sbp/src/messages/gnss.rs @@ -13,254 +13,479 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Various structs shared between modules +pub use carrier_phase::CarrierPhase; +pub use gnss_signal::GnssSignal; +pub use gnss_signal_dep::GnssSignalDep; +pub use gps_time::GpsTime; +pub use gps_time_dep::GpsTimeDep; +pub use gps_time_sec::GpsTimeSec; +pub use sv_id::SvId; -use super::lib::*; - -/// GNSS carrier phase measurement -/// -/// Carrier phase measurement in cycles represented as a 40-bit fixed point -/// number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of -/// fractional cycles. This phase has the same sign as the pseudorange. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct CarrierPhase { - /// Carrier phase whole cycles - #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] - pub i: i32, - /// Carrier phase fractional part - #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] - pub f: u8, -} +pub mod carrier_phase { + #![allow(unused_imports)] -impl WireFormat for CarrierPhase { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.i) + WireFormat::len(&self.f) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.i, buf); - WireFormat::write(&self.f, buf); + use super::*; + use crate::messages::lib::*; + + /// GNSS carrier phase measurement + /// + /// Carrier phase measurement in cycles represented as a 40-bit fixed point + /// number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of + /// fractional cycles. This phase has the same sign as the pseudorange. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct CarrierPhase { + /// Carrier phase whole cycles + #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] + pub i: i32, + /// Carrier phase fractional part + #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] + pub f: u8, } - fn parse_unchecked(buf: &mut B) -> Self { - CarrierPhase { - i: WireFormat::parse_unchecked(buf), - f: WireFormat::parse_unchecked(buf), + + impl WireFormat for CarrierPhase { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.i) + WireFormat::len(&self.f) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.i, buf); + WireFormat::write(&self.f, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + CarrierPhase { + i: WireFormat::parse_unchecked(buf), + f: WireFormat::parse_unchecked(buf), + } } } } -/// Nanosecond-accurate receiver clock time -/// -/// A wire-appropriate receiver clock time, defined as the time since the -/// beginning of the week on the Saturday/Sunday transition. In most cases, -/// observations are epoch aligned so ns field will be 0. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GpsTime { - /// Milliseconds since start of GPS week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to - /// 500000) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] - pub ns_residual: i32, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, -} +pub mod gps_time { + #![allow(unused_imports)] -impl WireFormat for GpsTime { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) + WireFormat::len(&self.ns_residual) + WireFormat::len(&self.wn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.ns_residual, buf); - WireFormat::write(&self.wn, buf); + use super::*; + use crate::messages::lib::*; + + /// Nanosecond-accurate receiver clock time + /// + /// A wire-appropriate receiver clock time, defined as the time since the + /// beginning of the week on the Saturday/Sunday transition. In most cases, + /// observations are epoch aligned so ns field will be 0. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GpsTime { + /// Milliseconds since start of GPS week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to + /// 500000) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] + pub ns_residual: i32, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, } - fn parse_unchecked(buf: &mut B) -> Self { - GpsTime { - tow: WireFormat::parse_unchecked(buf), - ns_residual: WireFormat::parse_unchecked(buf), - wn: WireFormat::parse_unchecked(buf), + + impl WireFormat for GpsTime { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.ns_residual) + + WireFormat::len(&self.wn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.ns_residual, buf); + WireFormat::write(&self.wn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GpsTime { + tow: WireFormat::parse_unchecked(buf), + ns_residual: WireFormat::parse_unchecked(buf), + wn: WireFormat::parse_unchecked(buf), + } } } } -/// Millisecond-accurate GPS time -/// -/// A wire-appropriate GPS time, defined as the number of milliseconds since -/// beginning of the week on the Saturday/Sunday transition. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GpsTimeDep { - /// Milliseconds since start of GPS week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, -} +pub mod gps_time_dep { + #![allow(unused_imports)] -impl WireFormat for GpsTimeDep { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) + WireFormat::len(&self.wn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.wn, buf); + use super::*; + use crate::messages::lib::*; + + /// Millisecond-accurate GPS time + /// + /// A wire-appropriate GPS time, defined as the number of milliseconds since + /// beginning of the week on the Saturday/Sunday transition. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GpsTimeDep { + /// Milliseconds since start of GPS week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, } - fn parse_unchecked(buf: &mut B) -> Self { - GpsTimeDep { - tow: WireFormat::parse_unchecked(buf), - wn: WireFormat::parse_unchecked(buf), + + impl WireFormat for GpsTimeDep { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + WireFormat::len(&self.wn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.wn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GpsTimeDep { + tow: WireFormat::parse_unchecked(buf), + wn: WireFormat::parse_unchecked(buf), + } } } } -/// Whole second accurate GPS time -/// -/// A GPS time, defined as the number of seconds since beginning of the week -/// on the Saturday/Sunday transition. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GpsTimeSec { - /// Seconds since start of GPS week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, +pub mod gps_time_sec { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Whole second accurate GPS time + /// + /// A GPS time, defined as the number of seconds since beginning of the week + /// on the Saturday/Sunday transition. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GpsTimeSec { + /// Seconds since start of GPS week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, + } + + impl WireFormat for GpsTimeSec { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + WireFormat::len(&self.wn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.wn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GpsTimeSec { + tow: WireFormat::parse_unchecked(buf), + wn: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for GpsTimeSec { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) + WireFormat::len(&self.wn) +pub mod gnss_signal { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Represents all the relevant information about the signal + /// + /// Signal identifier containing constellation, band, and satellite + /// identifier. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GnssSignal { + /// Constellation-specific satellite identifier. This field for Glonass can + /// either be (100+FCN) where FCN is in \[-7,+6\] or the Slot ID in \[1,28\]. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sat")))] + pub sat: u8, + /// Signal constellation, band and code + #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] + pub code: u8, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.wn, buf); + + impl GnssSignal { + /// Gets the [Code][self::Code] stored in the `code` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Code` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `Code` were added. + pub fn code(&self) -> Result { + get_bit_range!(self.code, u8, u8, 7, 0).try_into() + } + + /// Set the bitrange corresponding to the [Code][Code] of the `code` bitfield. + pub fn set_code(&mut self, code: Code) { + set_bit_range!(&mut self.code, code, u8, u8, 7, 0); + } } - fn parse_unchecked(buf: &mut B) -> Self { - GpsTimeSec { - tow: WireFormat::parse_unchecked(buf), - wn: WireFormat::parse_unchecked(buf), + + impl WireFormat for GnssSignal { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sat) + WireFormat::len(&self.code) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sat, buf); + WireFormat::write(&self.code, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GnssSignal { + sat: WireFormat::parse_unchecked(buf), + code: WireFormat::parse_unchecked(buf), + } } } -} -/// Represents all the relevant information about the signal -/// -/// Signal identifier containing constellation, band, and satellite -/// identifier. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GnssSignal { - /// Constellation-specific satellite identifier. This field for Glonass can - /// either be (100+FCN) where FCN is in \[-7,+6\] or the Slot ID in \[1,28\]. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sat")))] - pub sat: u8, - /// Signal constellation, band and code - #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] - pub code: u8, -} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Code { + /// GPS L1CA + GpsL1Ca = 0, + + /// GPS L2CM + GpsL2Cm = 1, + + /// SBAS L1CA + SbasL1Ca = 2, + + /// GLO L1CA + GloL1Ca = 3, + + /// GLO L2CA + GloL2Ca = 4, + + /// GPS L1P + GpsL1P = 5, -impl WireFormat for GnssSignal { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sat) + WireFormat::len(&self.code) + /// GPS L2P + GpsL2P = 6, + + /// BDS2 B1 + Bds2B1 = 12, + + /// BDS2 B2 + Bds2B2 = 13, + + /// GAL E1B + GalE1B = 14, + + /// GAL E7I + GalE7I = 20, + + /// BDS3 B2a + Bds3B2A = 47, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sat, buf); - WireFormat::write(&self.code, buf); + + impl std::fmt::Display for Code { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Code::GpsL1Ca => f.write_str("GPS L1CA"), + Code::GpsL2Cm => f.write_str("GPS L2CM"), + Code::SbasL1Ca => f.write_str("SBAS L1CA"), + Code::GloL1Ca => f.write_str("GLO L1CA"), + Code::GloL2Ca => f.write_str("GLO L2CA"), + Code::GpsL1P => f.write_str("GPS L1P"), + Code::GpsL2P => f.write_str("GPS L2P"), + Code::Bds2B1 => f.write_str("BDS2 B1"), + Code::Bds2B2 => f.write_str("BDS2 B2"), + Code::GalE1B => f.write_str("GAL E1B"), + Code::GalE7I => f.write_str("GAL E7I"), + Code::Bds3B2A => f.write_str("BDS3 B2a"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - GnssSignal { - sat: WireFormat::parse_unchecked(buf), - code: WireFormat::parse_unchecked(buf), + + impl TryFrom for Code { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(Code::GpsL1Ca), + 1 => Ok(Code::GpsL2Cm), + 2 => Ok(Code::SbasL1Ca), + 3 => Ok(Code::GloL1Ca), + 4 => Ok(Code::GloL2Ca), + 5 => Ok(Code::GpsL1P), + 6 => Ok(Code::GpsL2P), + 12 => Ok(Code::Bds2B1), + 13 => Ok(Code::Bds2B2), + 14 => Ok(Code::GalE1B), + 20 => Ok(Code::GalE7I), + 47 => Ok(Code::Bds3B2A), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GnssSignalDep { - /// Constellation-specific satellite identifier. +pub mod gnss_signal_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Deprecated /// - /// Note: unlike GnssSignal, GPS satellites are encoded as (PRN - 1). Other - /// constellations do not have this offset. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sat")))] - pub sat: u16, - /// Signal constellation, band and code - #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] - pub code: u8, - /// Reserved - #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] - pub reserved: u8, -} + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GnssSignalDep { + /// Constellation-specific satellite identifier. + /// + /// Note: unlike GnssSignal, GPS satellites are encoded as (PRN - 1). Other + /// constellations do not have this offset. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sat")))] + pub sat: u16, + /// Signal constellation, band and code + #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] + pub code: u8, + /// Reserved + #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] + pub reserved: u8, + } + + impl GnssSignalDep { + /// Gets the [Code][self::Code] stored in the `code` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Code` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `Code` were added. + pub fn code(&self) -> Result { + get_bit_range!(self.code, u8, u8, 7, 0).try_into() + } + + /// Set the bitrange corresponding to the [Code][Code] of the `code` bitfield. + pub fn set_code(&mut self, code: Code) { + set_bit_range!(&mut self.code, code, u8, u8, 7, 0); + } + } -impl WireFormat for GnssSignalDep { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sat) + WireFormat::len(&self.code) + WireFormat::len(&self.reserved) + impl WireFormat for GnssSignalDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sat) + + WireFormat::len(&self.code) + + WireFormat::len(&self.reserved) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sat, buf); + WireFormat::write(&self.code, buf); + WireFormat::write(&self.reserved, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GnssSignalDep { + sat: WireFormat::parse_unchecked(buf), + code: WireFormat::parse_unchecked(buf), + reserved: WireFormat::parse_unchecked(buf), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sat, buf); - WireFormat::write(&self.code, buf); - WireFormat::write(&self.reserved, buf); + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Code { + /// GPS L1CA + GpsL1Ca = 0, + + /// GPS L2CM + GpsL2Cm = 1, + + /// SBAS L1CA + SbasL1Ca = 2, + + /// GLO L1CA + GloL1Ca = 3, + + /// GLO L2CA + GloL2Ca = 4, + + /// GPS L1P + GpsL1P = 5, + + /// GPS L2P + GpsL2P = 6, } - fn parse_unchecked(buf: &mut B) -> Self { - GnssSignalDep { - sat: WireFormat::parse_unchecked(buf), - code: WireFormat::parse_unchecked(buf), - reserved: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for Code { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Code::GpsL1Ca => f.write_str("GPS L1CA"), + Code::GpsL2Cm => f.write_str("GPS L2CM"), + Code::SbasL1Ca => f.write_str("SBAS L1CA"), + Code::GloL1Ca => f.write_str("GLO L1CA"), + Code::GloL2Ca => f.write_str("GLO L2CA"), + Code::GpsL1P => f.write_str("GPS L1P"), + Code::GpsL2P => f.write_str("GPS L2P"), + } } } -} -/// Space vehicle identifier -/// -/// A (Constellation ID, satellite ID) tuple that uniquely identifies a space -/// vehicle. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct SvId { - /// ID of the space vehicle within its constellation - #[cfg_attr(feature = "serde", serde(rename(serialize = "satId")))] - pub sat_id: u8, - /// Constellation ID to which the SV belongs - #[cfg_attr(feature = "serde", serde(rename(serialize = "constellation")))] - pub constellation: u8, + impl TryFrom for Code { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(Code::GpsL1Ca), + 1 => Ok(Code::GpsL2Cm), + 2 => Ok(Code::SbasL1Ca), + 3 => Ok(Code::GloL1Ca), + 4 => Ok(Code::GloL2Ca), + 5 => Ok(Code::GpsL1P), + 6 => Ok(Code::GpsL2P), + i => Err(i), + } + } + } } -impl WireFormat for SvId { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sat_id) + WireFormat::len(&self.constellation) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sat_id, buf); - WireFormat::write(&self.constellation, buf); +pub mod sv_id { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Space vehicle identifier + /// + /// A (Constellation ID, satellite ID) tuple that uniquely identifies a space + /// vehicle. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct SvId { + /// ID of the space vehicle within its constellation + #[cfg_attr(feature = "serde", serde(rename(serialize = "satId")))] + pub sat_id: u8, + /// Constellation ID to which the SV belongs + #[cfg_attr(feature = "serde", serde(rename(serialize = "constellation")))] + pub constellation: u8, } - fn parse_unchecked(buf: &mut B) -> Self { - SvId { - sat_id: WireFormat::parse_unchecked(buf), - constellation: WireFormat::parse_unchecked(buf), + + impl WireFormat for SvId { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sat_id) + WireFormat::len(&self.constellation) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sat_id, buf); + WireFormat::write(&self.constellation, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + SvId { + sat_id: WireFormat::parse_unchecked(buf), + constellation: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/imu.rs b/rust/sbp/src/messages/imu.rs index dc6d8a16a9..b442d2680a 100644 --- a/rust/sbp/src/messages/imu.rs +++ b/rust/sbp/src/messages/imu.rs @@ -13,219 +13,475 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Inertial Measurement Unit (IMU) messages. +pub use msg_imu_aux::MsgImuAux; +pub use msg_imu_raw::MsgImuRaw; -use super::lib::*; - -/// Auxiliary IMU data -/// -/// Auxiliary data specific to a particular IMU. The `imu_type` field will -/// always be consistent but the rest of the payload is device specific and -/// depends on the value of `imu_type`. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgImuAux { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// IMU type - #[cfg_attr(feature = "serde", serde(rename(serialize = "imu_type")))] - pub imu_type: u8, - /// Raw IMU temperature - #[cfg_attr(feature = "serde", serde(rename(serialize = "temp")))] - pub temp: i16, - /// IMU configuration - #[cfg_attr(feature = "serde", serde(rename(serialize = "imu_conf")))] - pub imu_conf: u8, -} +pub mod msg_imu_aux { + #![allow(unused_imports)] -impl ConcreteMessage for MsgImuAux { - const MESSAGE_TYPE: u16 = 2305; - const MESSAGE_NAME: &'static str = "MSG_IMU_AUX"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgImuAux { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Auxiliary IMU data + /// + /// Auxiliary data specific to a particular IMU. The `imu_type` field will + /// always be consistent but the rest of the payload is device specific and + /// depends on the value of `imu_type`. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgImuAux { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// IMU type + #[cfg_attr(feature = "serde", serde(rename(serialize = "imu_type")))] + pub imu_type: u8, + /// Raw IMU temperature + #[cfg_attr(feature = "serde", serde(rename(serialize = "temp")))] + pub temp: i16, + /// IMU configuration + #[cfg_attr(feature = "serde", serde(rename(serialize = "imu_conf")))] + pub imu_conf: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgImuAux { + /// Gets the [ImuType][self::ImuType] stored in the `imu_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ImuType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ImuType` were added. + pub fn imu_type(&self) -> Result { + get_bit_range!(self.imu_type, u8, u8, 7, 0).try_into() + } + + /// Set the bitrange corresponding to the [ImuType][ImuType] of the `imu_type` bitfield. + pub fn set_imu_type(&mut self, imu_type: ImuType) { + set_bit_range!(&mut self.imu_type, imu_type, u8, u8, 7, 0); + } + + /// Gets the [GyroscopeRange][self::GyroscopeRange] stored in the `imu_conf` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `GyroscopeRange` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `GyroscopeRange` were added. + pub fn gyroscope_range(&self) -> Result { + get_bit_range!(self.imu_conf, u8, u8, 7, 4).try_into() + } + + /// Set the bitrange corresponding to the [GyroscopeRange][GyroscopeRange] of the `imu_conf` bitfield. + pub fn set_gyroscope_range(&mut self, gyroscope_range: GyroscopeRange) { + set_bit_range!(&mut self.imu_conf, gyroscope_range, u8, u8, 7, 4); + } + + /// Gets the [AccelerometerRange][self::AccelerometerRange] stored in the `imu_conf` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AccelerometerRange` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AccelerometerRange` were added. + pub fn accelerometer_range(&self) -> Result { + get_bit_range!(self.imu_conf, u8, u8, 3, 0).try_into() + } + + /// Set the bitrange corresponding to the [AccelerometerRange][AccelerometerRange] of the `imu_conf` bitfield. + pub fn set_accelerometer_range(&mut self, accelerometer_range: AccelerometerRange) { + set_bit_range!(&mut self.imu_conf, accelerometer_range, u8, u8, 3, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgImuAux { + const MESSAGE_TYPE: u16 = 2305; + const MESSAGE_NAME: &'static str = "MSG_IMU_AUX"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgImuAux { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgImuAux { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgImuAux(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgImuAux { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgImuAux(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgImuAux { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.imu_type) + + WireFormat::len(&self.temp) + + WireFormat::len(&self.imu_conf) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.imu_type, buf); + WireFormat::write(&self.temp, buf); + WireFormat::write(&self.imu_conf, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgImuAux { + sender_id: None, + imu_type: WireFormat::parse_unchecked(buf), + temp: WireFormat::parse_unchecked(buf), + imu_conf: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgImuAux { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.imu_type) - + WireFormat::len(&self.temp) - + WireFormat::len(&self.imu_conf) + /// IMU Type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ImuType { + /// Bosch BMI160 + BoschBmi160 = 0, + + /// ST Microelectronics ASM330LLH + StMicroelectronicsAsm330Llh = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.imu_type, buf); - WireFormat::write(&self.temp, buf); - WireFormat::write(&self.imu_conf, buf); + + impl std::fmt::Display for ImuType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ImuType::BoschBmi160 => f.write_str("Bosch BMI160"), + ImuType::StMicroelectronicsAsm330Llh => { + f.write_str("ST Microelectronics ASM330LLH") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgImuAux { - sender_id: None, - imu_type: WireFormat::parse_unchecked(buf), - temp: WireFormat::parse_unchecked(buf), - imu_conf: WireFormat::parse_unchecked(buf), + + impl TryFrom for ImuType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ImuType::BoschBmi160), + 1 => Ok(ImuType::StMicroelectronicsAsm330Llh), + i => Err(i), + } } } -} -/// Raw IMU data -/// -/// Raw data from the Inertial Measurement Unit, containing accelerometer and -/// gyroscope readings. The sense of the measurements are to be aligned with -/// the indications on the device itself. Measurement units, which are -/// specific to the device hardware and settings, are communicated via the -/// MSG_IMU_AUX message. If using "time since startup" time tags, the -/// receiving end will expect a `MSG_GNSS_TIME_OFFSET` when a PVT fix becomes -/// available to synchronise IMU measurements with GNSS. The timestamp must -/// wrap around to zero when reaching one week (604800 seconds). -/// -/// The time-tagging mode should not change throughout a run. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgImuRaw { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Milliseconds since reference epoch and time status. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Milliseconds since reference epoch, fractional part - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_f")))] - pub tow_f: u8, - /// Acceleration in the IMU frame X axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_x")))] - pub acc_x: i16, - /// Acceleration in the IMU frame Y axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_y")))] - pub acc_y: i16, - /// Acceleration in the IMU frame Z axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_z")))] - pub acc_z: i16, - /// Angular rate around IMU frame X axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_x")))] - pub gyr_x: i16, - /// Angular rate around IMU frame Y axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_y")))] - pub gyr_y: i16, - /// Angular rate around IMU frame Z axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_z")))] - pub gyr_z: i16, -} + /// Gyroscope Range + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum GyroscopeRange { + /// +/- 2000 deg / s + _2000DegS = 0, -impl ConcreteMessage for MsgImuRaw { - const MESSAGE_TYPE: u16 = 2304; - const MESSAGE_NAME: &'static str = "MSG_IMU_RAW"; -} + /// +/- 1000 deg / s + _1000DegS = 1, + + /// +/- 500 deg / s + _500DegS = 2, -impl SbpMessage for MsgImuRaw { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// +/- 250 deg / s + _250DegS = 3, + + /// +/- 125 deg / s + _125DegS = 4, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for GyroscopeRange { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GyroscopeRange::_2000DegS => f.write_str("+/- 2000 deg / s"), + GyroscopeRange::_1000DegS => f.write_str("+/- 1000 deg / s"), + GyroscopeRange::_500DegS => f.write_str("+/- 500 deg / s"), + GyroscopeRange::_250DegS => f.write_str("+/- 250 deg / s"), + GyroscopeRange::_125DegS => f.write_str("+/- 125 deg / s"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for GyroscopeRange { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(GyroscopeRange::_2000DegS), + 1 => Ok(GyroscopeRange::_1000DegS), + 2 => Ok(GyroscopeRange::_500DegS), + 3 => Ok(GyroscopeRange::_250DegS), + 4 => Ok(GyroscopeRange::_125DegS), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Accelerometer Range + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AccelerometerRange { + /// +/- 2g + _2G = 0, + + /// +/- 4g + _4G = 1, + + /// +/- 8g + _8G = 2, + + /// +/- 16g + _16G = 3, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for AccelerometerRange { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AccelerometerRange::_2G => f.write_str("+/- 2g"), + AccelerometerRange::_4G => f.write_str("+/- 4g"), + AccelerometerRange::_8G => f.write_str("+/- 8g"), + AccelerometerRange::_16G => f.write_str("+/- 16g"), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - const IMU_RAW_TIME_STATUS_MASK: u32 = (1 << 30) | (1 << 31); - if self.tow & IMU_RAW_TIME_STATUS_MASK != 0 { - return None; + + impl TryFrom for AccelerometerRange { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AccelerometerRange::_2G), + 1 => Ok(AccelerometerRange::_4G), + 2 => Ok(AccelerometerRange::_8G), + 3 => Ok(AccelerometerRange::_16G), + i => Err(i), + } } - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -impl TryFrom for MsgImuRaw { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgImuRaw(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_imu_raw { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Raw IMU data + /// + /// Raw data from the Inertial Measurement Unit, containing accelerometer and + /// gyroscope readings. The sense of the measurements are to be aligned with + /// the indications on the device itself. Measurement units, which are + /// specific to the device hardware and settings, are communicated via the + /// MSG_IMU_AUX message. If using "time since startup" time tags, the + /// receiving end will expect a `MSG_GNSS_TIME_OFFSET` when a PVT fix becomes + /// available to synchronise IMU measurements with GNSS. The timestamp must + /// wrap around to zero when reaching one week (604800 seconds). + /// + /// The time-tagging mode should not change throughout a run. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgImuRaw { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Milliseconds since reference epoch and time status. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Milliseconds since reference epoch, fractional part + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_f")))] + pub tow_f: u8, + /// Acceleration in the IMU frame X axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_x")))] + pub acc_x: i16, + /// Acceleration in the IMU frame Y axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_y")))] + pub acc_y: i16, + /// Acceleration in the IMU frame Z axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc_z")))] + pub acc_z: i16, + /// Angular rate around IMU frame X axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_x")))] + pub gyr_x: i16, + /// Angular rate around IMU frame Y axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_y")))] + pub gyr_y: i16, + /// Angular rate around IMU frame Z axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "gyr_z")))] + pub gyr_z: i16, + } + + impl MsgImuRaw { + /// Gets the [TimeStatus][self::TimeStatus] stored in the `tow` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeStatus` were added. + pub fn time_status(&self) -> Result { + get_bit_range!(self.tow, u32, u8, 31, 30).try_into() + } + + /// Set the bitrange corresponding to the [TimeStatus][TimeStatus] of the `tow` bitfield. + pub fn set_time_status(&mut self, time_status: TimeStatus) { + set_bit_range!(&mut self.tow, time_status, u32, u8, 31, 30); + } + + /// Gets the `time_since_reference_epoch_in_milliseconds` stored in `tow`. + pub fn time_since_reference_epoch_in_milliseconds(&self) -> u32 { + get_bit_range!(self.tow, u32, u32, 29, 0) + } + + /// Sets the `time_since_reference_epoch_in_milliseconds` bitrange of `tow`. + pub fn set_time_since_reference_epoch_in_milliseconds( + &mut self, + time_since_reference_epoch_in_milliseconds: u32, + ) { + set_bit_range!( + &mut self.tow, + time_since_reference_epoch_in_milliseconds, + u32, + u32, + 29, + 0 + ); + } + } + + impl ConcreteMessage for MsgImuRaw { + const MESSAGE_TYPE: u16 = 2304; + const MESSAGE_NAME: &'static str = "MSG_IMU_RAW"; + } + + impl SbpMessage for MsgImuRaw { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + const IMU_RAW_TIME_STATUS_MASK: u32 = (1 << 30) | (1 << 31); + if self.tow & IMU_RAW_TIME_STATUS_MASK != 0 { + return None; + } + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgImuRaw { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgImuRaw(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgImuRaw { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.tow_f) + + WireFormat::len(&self.acc_x) + + WireFormat::len(&self.acc_y) + + WireFormat::len(&self.acc_z) + + WireFormat::len(&self.gyr_x) + + WireFormat::len(&self.gyr_y) + + WireFormat::len(&self.gyr_z) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.tow_f, buf); + WireFormat::write(&self.acc_x, buf); + WireFormat::write(&self.acc_y, buf); + WireFormat::write(&self.acc_z, buf); + WireFormat::write(&self.gyr_x, buf); + WireFormat::write(&self.gyr_y, buf); + WireFormat::write(&self.gyr_z, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgImuRaw { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + tow_f: WireFormat::parse_unchecked(buf), + acc_x: WireFormat::parse_unchecked(buf), + acc_y: WireFormat::parse_unchecked(buf), + acc_z: WireFormat::parse_unchecked(buf), + gyr_x: WireFormat::parse_unchecked(buf), + gyr_y: WireFormat::parse_unchecked(buf), + gyr_z: WireFormat::parse_unchecked(buf), + } + } + } + + /// Time status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeStatus { + /// Reference epoch is start of current GPS week + ReferenceEpochIsStartOfCurrentGpsWeek = 0, + + /// Reference epoch is time of system startup + ReferenceEpochIsTimeOfSystemStartup = 1, + + /// Reference epoch is unknown + ReferenceEpochIsUnknown = 2, + + /// Reference epoch is last PPS + ReferenceEpochIsLastPps = 3, + } + + impl std::fmt::Display for TimeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek => { + f.write_str("Reference epoch is start of current GPS week") + } + TimeStatus::ReferenceEpochIsTimeOfSystemStartup => { + f.write_str("Reference epoch is time of system startup") + } + TimeStatus::ReferenceEpochIsUnknown => f.write_str("Reference epoch is unknown"), + TimeStatus::ReferenceEpochIsLastPps => f.write_str("Reference epoch is last PPS"), + } } } -} -impl WireFormat for MsgImuRaw { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.tow_f) - + WireFormat::len(&self.acc_x) - + WireFormat::len(&self.acc_y) - + WireFormat::len(&self.acc_z) - + WireFormat::len(&self.gyr_x) - + WireFormat::len(&self.gyr_y) - + WireFormat::len(&self.gyr_z) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.tow_f, buf); - WireFormat::write(&self.acc_x, buf); - WireFormat::write(&self.acc_y, buf); - WireFormat::write(&self.acc_z, buf); - WireFormat::write(&self.gyr_x, buf); - WireFormat::write(&self.gyr_y, buf); - WireFormat::write(&self.gyr_z, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgImuRaw { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - tow_f: WireFormat::parse_unchecked(buf), - acc_x: WireFormat::parse_unchecked(buf), - acc_y: WireFormat::parse_unchecked(buf), - acc_z: WireFormat::parse_unchecked(buf), - gyr_x: WireFormat::parse_unchecked(buf), - gyr_y: WireFormat::parse_unchecked(buf), - gyr_z: WireFormat::parse_unchecked(buf), + impl TryFrom for TimeStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek), + 1 => Ok(TimeStatus::ReferenceEpochIsTimeOfSystemStartup), + 2 => Ok(TimeStatus::ReferenceEpochIsUnknown), + 3 => Ok(TimeStatus::ReferenceEpochIsLastPps), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/linux.rs b/rust/sbp/src/messages/linux.rs index 4417b61314..1e0cbbc20d 100644 --- a/rust/sbp/src/messages/linux.rs +++ b/rust/sbp/src/messages/linux.rs @@ -13,1087 +13,1311 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Linux state monitoring. +pub use msg_linux_cpu_state::MsgLinuxCpuState; +pub use msg_linux_cpu_state_dep_a::MsgLinuxCpuStateDepA; +pub use msg_linux_mem_state::MsgLinuxMemState; +pub use msg_linux_mem_state_dep_a::MsgLinuxMemStateDepA; +pub use msg_linux_process_fd_count::MsgLinuxProcessFdCount; +pub use msg_linux_process_fd_summary::MsgLinuxProcessFdSummary; +pub use msg_linux_process_socket_counts::MsgLinuxProcessSocketCounts; +pub use msg_linux_process_socket_queues::MsgLinuxProcessSocketQueues; +pub use msg_linux_socket_usage::MsgLinuxSocketUsage; +pub use msg_linux_sys_state::MsgLinuxSysState; +pub use msg_linux_sys_state_dep_a::MsgLinuxSysStateDepA; -use super::lib::*; - -/// List CPU state on the system -/// -/// This message indicates the process state of the top 10 heaviest consumers -/// of CPU on the system, including a timestamp. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxCpuState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// percent of CPU used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] - pub pcpu: u8, - /// timestamp of message, refer to flags field for how to interpret - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u32, - /// flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// fixed length string representing the thread name - #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] - pub tname: SbpString<[u8; 15], Unterminated>, - /// the command line (as much as it fits in the remaining packet) - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} +pub mod msg_linux_cpu_state { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxCpuState { - const MESSAGE_TYPE: u16 = 32520; - const MESSAGE_NAME: &'static str = "MSG_LINUX_CPU_STATE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxCpuState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// List CPU state on the system + /// + /// This message indicates the process state of the top 10 heaviest consumers + /// of CPU on the system, including a timestamp. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxCpuState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// percent of CPU used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] + pub pcpu: u8, + /// timestamp of message, refer to flags field for how to interpret + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u32, + /// flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// fixed length string representing the thread name + #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] + pub tname: SbpString<[u8; 15], Unterminated>, + /// the command line (as much as it fits in the remaining packet) + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + + impl MsgLinuxCpuState { + /// Gets the [TimestampType][self::TimestampType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimestampType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimestampType` were added. + pub fn timestamp_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimestampType][TimestampType] of the `flags` bitfield. + pub fn set_timestamp_type(&mut self, timestamp_type: TimestampType) { + set_bit_range!(&mut self.flags, timestamp_type, u8, u8, 2, 0); + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxCpuState { + const MESSAGE_TYPE: u16 = 32520; + const MESSAGE_NAME: &'static str = "MSG_LINUX_CPU_STATE"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxCpuState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxCpuState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxCpuState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxCpuState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxCpuState(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxCpuState { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.pcpu) - + WireFormat::len(&self.time) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.tname) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.pcpu, buf); - WireFormat::write(&self.time, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.tname, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxCpuState { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - pcpu: WireFormat::parse_unchecked(buf), - time: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - tname: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxCpuState { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.pcpu) + + WireFormat::len(&self.time) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.tname) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.pcpu, buf); + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.tname, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxCpuState { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + pcpu: WireFormat::parse_unchecked(buf), + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + tname: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } -} -/// List CPU state on the system. DEPRECATED -/// -/// This message indicates the process state of the top 10 heaviest consumers -/// of CPU on the system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxCpuStateDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// percent of cpu used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] - pub pcpu: u8, - /// fixed length string representing the thread name - #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] - pub tname: SbpString<[u8; 15], Unterminated>, - /// the command line (as much as it fits in the remaining packet) - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} + /// timestamp type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimestampType { + /// System time in seconds + SystemTimeInSeconds = 0, -impl ConcreteMessage for MsgLinuxCpuStateDepA { - const MESSAGE_TYPE: u16 = 32512; - const MESSAGE_NAME: &'static str = "MSG_LINUX_CPU_STATE_DEP_A"; -} + /// GPS TOW in milliseconds + GpsTowInMilliseconds = 1, + } -impl SbpMessage for MsgLinuxCpuStateDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for TimestampType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimestampType::SystemTimeInSeconds => f.write_str("System time in seconds"), + TimestampType::GpsTowInMilliseconds => f.write_str("GPS TOW in milliseconds"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for TimestampType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimestampType::SystemTimeInSeconds), + 1 => Ok(TimestampType::GpsTowInMilliseconds), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id +} + +pub mod msg_linux_cpu_state_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// List CPU state on the system. DEPRECATED + /// + /// This message indicates the process state of the top 10 heaviest consumers + /// of CPU on the system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxCpuStateDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// percent of cpu used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] + pub pcpu: u8, + /// fixed length string representing the thread name + #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] + pub tname: SbpString<[u8; 15], Unterminated>, + /// the command line (as much as it fits in the remaining packet) + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxCpuStateDepA { + const MESSAGE_TYPE: u16 = 32512; + const MESSAGE_NAME: &'static str = "MSG_LINUX_CPU_STATE_DEP_A"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxCpuStateDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxCpuStateDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxCpuStateDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxCpuStateDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxCpuStateDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxCpuStateDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.pcpu) - + WireFormat::len(&self.tname) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.pcpu, buf); - WireFormat::write(&self.tname, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxCpuStateDepA { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - pcpu: WireFormat::parse_unchecked(buf), - tname: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxCpuStateDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.pcpu) + + WireFormat::len(&self.tname) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.pcpu, buf); + WireFormat::write(&self.tname, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxCpuStateDepA { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + pcpu: WireFormat::parse_unchecked(buf), + tname: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } } -/// List memory state on the system -/// -/// This message indicates the process state of the top 10 heaviest consumers -/// of memory on the system, including a timestamp. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxMemState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// percent of memory used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] - pub pmem: u8, - /// timestamp of message, refer to flags field for how to interpret - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u32, - /// flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// fixed length string representing the thread name - #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] - pub tname: SbpString<[u8; 15], Unterminated>, - /// the command line (as much as it fits in the remaining packet) - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} +pub mod msg_linux_mem_state { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxMemState { - const MESSAGE_TYPE: u16 = 32521; - const MESSAGE_NAME: &'static str = "MSG_LINUX_MEM_STATE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxMemState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// List memory state on the system + /// + /// This message indicates the process state of the top 10 heaviest consumers + /// of memory on the system, including a timestamp. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxMemState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// percent of memory used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] + pub pmem: u8, + /// timestamp of message, refer to flags field for how to interpret + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u32, + /// flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// fixed length string representing the thread name + #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] + pub tname: SbpString<[u8; 15], Unterminated>, + /// the command line (as much as it fits in the remaining packet) + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn sender_id(&self) -> Option { - self.sender_id + + impl MsgLinuxMemState { + /// Gets the [TimestampType][self::TimestampType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimestampType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimestampType` were added. + pub fn timestamp_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimestampType][TimestampType] of the `flags` bitfield. + pub fn set_timestamp_type(&mut self, timestamp_type: TimestampType) { + set_bit_range!(&mut self.flags, timestamp_type, u8, u8, 2, 0); + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxMemState { + const MESSAGE_TYPE: u16 = 32521; + const MESSAGE_NAME: &'static str = "MSG_LINUX_MEM_STATE"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxMemState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxMemState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxMemState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxMemState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxMemState(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxMemState { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.pmem) - + WireFormat::len(&self.time) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.tname) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.pmem, buf); - WireFormat::write(&self.time, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.tname, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxMemState { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - pmem: WireFormat::parse_unchecked(buf), - time: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - tname: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxMemState { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.pmem) + + WireFormat::len(&self.time) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.tname) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.pmem, buf); + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.tname, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxMemState { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + pmem: WireFormat::parse_unchecked(buf), + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + tname: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } -} -/// List memory state on the system. DEPRECATED -/// -/// This message indicates the process state of the top 10 heaviest consumers -/// of memory on the system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxMemStateDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// percent of memory used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] - pub pmem: u8, - /// fixed length string representing the thread name - #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] - pub tname: SbpString<[u8; 15], Unterminated>, - /// the command line (as much as it fits in the remaining packet) - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} + /// timestamp type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimestampType { + /// System time in seconds + SystemTimeInSeconds = 0, -impl ConcreteMessage for MsgLinuxMemStateDepA { - const MESSAGE_TYPE: u16 = 32513; - const MESSAGE_NAME: &'static str = "MSG_LINUX_MEM_STATE_DEP_A"; -} + /// GPS TOW in milliseconds + GpsTowInMilliseconds = 1, + } -impl SbpMessage for MsgLinuxMemStateDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for TimestampType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimestampType::SystemTimeInSeconds => f.write_str("System time in seconds"), + TimestampType::GpsTowInMilliseconds => f.write_str("GPS TOW in milliseconds"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for TimestampType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimestampType::SystemTimeInSeconds), + 1 => Ok(TimestampType::GpsTowInMilliseconds), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id +} + +pub mod msg_linux_mem_state_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// List memory state on the system. DEPRECATED + /// + /// This message indicates the process state of the top 10 heaviest consumers + /// of memory on the system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxMemStateDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// percent of memory used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] + pub pmem: u8, + /// fixed length string representing the thread name + #[cfg_attr(feature = "serde", serde(rename(serialize = "tname")))] + pub tname: SbpString<[u8; 15], Unterminated>, + /// the command line (as much as it fits in the remaining packet) + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxMemStateDepA { + const MESSAGE_TYPE: u16 = 32513; + const MESSAGE_NAME: &'static str = "MSG_LINUX_MEM_STATE_DEP_A"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxMemStateDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxMemStateDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxMemStateDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxMemStateDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxMemStateDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxMemStateDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.pmem) - + WireFormat::len(&self.tname) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.pmem, buf); - WireFormat::write(&self.tname, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxMemStateDepA { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - pmem: WireFormat::parse_unchecked(buf), - tname: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxMemStateDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.pmem) + + WireFormat::len(&self.tname) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.pmem, buf); + WireFormat::write(&self.tname, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxMemStateDepA { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + pmem: WireFormat::parse_unchecked(buf), + tname: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } } -/// Summary of processes with large amounts of open file descriptors -/// -/// Top 10 list of processes with a large number of open file descriptors. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxProcessFdCount { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// a count of the number of file descriptors opened by the process - #[cfg_attr(feature = "serde", serde(rename(serialize = "fd_count")))] - pub fd_count: u16, - /// the command line of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} +pub mod msg_linux_process_fd_count { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxProcessFdCount { - const MESSAGE_TYPE: u16 = 32518; - const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_FD_COUNT"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxProcessFdCount { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Summary of processes with large amounts of open file descriptors + /// + /// Top 10 list of processes with a large number of open file descriptors. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxProcessFdCount { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// a count of the number of file descriptors opened by the process + #[cfg_attr(feature = "serde", serde(rename(serialize = "fd_count")))] + pub fd_count: u16, + /// the command line of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxProcessFdCount { + const MESSAGE_TYPE: u16 = 32518; + const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_FD_COUNT"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxProcessFdCount { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxProcessFdCount { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxProcessFdCount(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxProcessFdCount { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxProcessFdCount(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxProcessFdCount { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.fd_count) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.fd_count, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxProcessFdCount { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - fd_count: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxProcessFdCount { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.fd_count) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.fd_count, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxProcessFdCount { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + fd_count: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } } -/// Summary of open file descriptors on the system -/// -/// Summary of open file descriptors on the system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxProcessFdSummary { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// count of total FDs open on the system - #[cfg_attr(feature = "serde", serde(rename(serialize = "sys_fd_count")))] - pub sys_fd_count: u32, - /// A null delimited list of strings which alternates between a string - /// representation of the process count and the file name whose count it - /// being reported. That is, in C string syntax - /// "32\0/var/log/syslog\012\0/tmp/foo\0" with the end of the list being 2 - /// NULL terminators in a row. - #[cfg_attr(feature = "serde", serde(rename(serialize = "most_opened")))] - pub most_opened: SbpString, DoubleNullTerminated>, -} +pub mod msg_linux_process_fd_summary { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxProcessFdSummary { - const MESSAGE_TYPE: u16 = 32519; - const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_FD_SUMMARY"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxProcessFdSummary { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Summary of open file descriptors on the system + /// + /// Summary of open file descriptors on the system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxProcessFdSummary { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// count of total FDs open on the system + #[cfg_attr(feature = "serde", serde(rename(serialize = "sys_fd_count")))] + pub sys_fd_count: u32, + /// A null delimited list of strings which alternates between a string + /// representation of the process count and the file name whose count it + /// being reported. That is, in C string syntax + /// "32\0/var/log/syslog\012\0/tmp/foo\0" with the end of the list being 2 + /// NULL terminators in a row. + #[cfg_attr(feature = "serde", serde(rename(serialize = "most_opened")))] + pub most_opened: SbpString, DoubleNullTerminated>, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgLinuxProcessFdSummary { + const MESSAGE_TYPE: u16 = 32519; + const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_FD_SUMMARY"; } -} -impl TryFrom for MsgLinuxProcessFdSummary { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxProcessFdSummary(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgLinuxProcessFdSummary { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgLinuxProcessFdSummary { - const MIN_LEN: usize = ::MIN_LEN - + , DoubleNullTerminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sys_fd_count) + WireFormat::len(&self.most_opened) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sys_fd_count, buf); - WireFormat::write(&self.most_opened, buf); + impl TryFrom for MsgLinuxProcessFdSummary { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxProcessFdSummary(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxProcessFdSummary { - sender_id: None, - sys_fd_count: WireFormat::parse_unchecked(buf), - most_opened: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgLinuxProcessFdSummary { + const MIN_LEN: usize = ::MIN_LEN + + , DoubleNullTerminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sys_fd_count) + WireFormat::len(&self.most_opened) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sys_fd_count, buf); + WireFormat::write(&self.most_opened, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxProcessFdSummary { + sender_id: None, + sys_fd_count: WireFormat::parse_unchecked(buf), + most_opened: WireFormat::parse_unchecked(buf), + } } } } -/// A list of processes with high socket counts -/// -/// Top 10 list of processes with high socket counts. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxProcessSocketCounts { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// the number of sockets the process is using - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_count")))] - pub socket_count: u16, - /// A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4 - /// (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown) - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_types")))] - pub socket_types: u16, - /// A bitfield indicating the socket states: 0x1 (established), 0x2 (syn- - /// sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time- - /// wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200 - /// (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown) - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_states")))] - pub socket_states: u16, - /// the command line of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} +pub mod msg_linux_process_socket_counts { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxProcessSocketCounts { - const MESSAGE_TYPE: u16 = 32515; - const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_SOCKET_COUNTS"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxProcessSocketCounts { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// A list of processes with high socket counts + /// + /// Top 10 list of processes with high socket counts. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxProcessSocketCounts { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// the number of sockets the process is using + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_count")))] + pub socket_count: u16, + /// A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4 + /// (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown) + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_types")))] + pub socket_types: u16, + /// A bitfield indicating the socket states: 0x1 (established), 0x2 (syn- + /// sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time- + /// wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200 + /// (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown) + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_states")))] + pub socket_states: u16, + /// the command line of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxProcessSocketCounts { + const MESSAGE_TYPE: u16 = 32515; + const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_SOCKET_COUNTS"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxProcessSocketCounts { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxProcessSocketCounts { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxProcessSocketCounts(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxProcessSocketCounts { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxProcessSocketCounts(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxProcessSocketCounts { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.socket_count) - + WireFormat::len(&self.socket_types) - + WireFormat::len(&self.socket_states) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.socket_count, buf); - WireFormat::write(&self.socket_types, buf); - WireFormat::write(&self.socket_states, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxProcessSocketCounts { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - socket_count: WireFormat::parse_unchecked(buf), - socket_types: WireFormat::parse_unchecked(buf), - socket_states: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxProcessSocketCounts { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.socket_count) + + WireFormat::len(&self.socket_types) + + WireFormat::len(&self.socket_states) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.socket_count, buf); + WireFormat::write(&self.socket_types, buf); + WireFormat::write(&self.socket_states, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxProcessSocketCounts { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + socket_count: WireFormat::parse_unchecked(buf), + socket_types: WireFormat::parse_unchecked(buf), + socket_states: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } } -/// A list of processes with deep socket queues -/// -/// Top 10 list of sockets with deep queues. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxProcessSocketQueues { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// sequence of this status message, values from 0-9 - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u8, - /// the PID of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] - pub pid: u16, - /// the total amount of receive data queued for this process - #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_queued")))] - pub recv_queued: u16, - /// the total amount of send data queued for this process - #[cfg_attr(feature = "serde", serde(rename(serialize = "send_queued")))] - pub send_queued: u16, - /// A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4 - /// (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown) - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_types")))] - pub socket_types: u16, - /// A bitfield indicating the socket states: 0x1 (established), 0x2 (syn- - /// sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time- - /// wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200 - /// (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown) - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_states")))] - pub socket_states: u16, - /// Address of the largest queue, remote or local depending on the - /// directionality of the connection. - #[cfg_attr(feature = "serde", serde(rename(serialize = "address_of_largest")))] - pub address_of_largest: SbpString<[u8; 64], Unterminated>, - /// the command line of the process in question - #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] - pub cmdline: SbpString, Unterminated>, -} +pub mod msg_linux_process_socket_queues { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxProcessSocketQueues { - const MESSAGE_TYPE: u16 = 32516; - const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_SOCKET_QUEUES"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxProcessSocketQueues { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// A list of processes with deep socket queues + /// + /// Top 10 list of sockets with deep queues. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxProcessSocketQueues { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// sequence of this status message, values from 0-9 + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u8, + /// the PID of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid")))] + pub pid: u16, + /// the total amount of receive data queued for this process + #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_queued")))] + pub recv_queued: u16, + /// the total amount of send data queued for this process + #[cfg_attr(feature = "serde", serde(rename(serialize = "send_queued")))] + pub send_queued: u16, + /// A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4 + /// (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown) + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_types")))] + pub socket_types: u16, + /// A bitfield indicating the socket states: 0x1 (established), 0x2 (syn- + /// sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time- + /// wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200 + /// (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown) + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_states")))] + pub socket_states: u16, + /// Address of the largest queue, remote or local depending on the + /// directionality of the connection. + #[cfg_attr(feature = "serde", serde(rename(serialize = "address_of_largest")))] + pub address_of_largest: SbpString<[u8; 64], Unterminated>, + /// the command line of the process in question + #[cfg_attr(feature = "serde", serde(rename(serialize = "cmdline")))] + pub cmdline: SbpString, Unterminated>, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxProcessSocketQueues { + const MESSAGE_TYPE: u16 = 32516; + const MESSAGE_NAME: &'static str = "MSG_LINUX_PROCESS_SOCKET_QUEUES"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxProcessSocketQueues { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxProcessSocketQueues { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxProcessSocketQueues(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxProcessSocketQueues { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxProcessSocketQueues(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxProcessSocketQueues { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - + WireFormat::len(&self.pid) - + WireFormat::len(&self.recv_queued) - + WireFormat::len(&self.send_queued) - + WireFormat::len(&self.socket_types) - + WireFormat::len(&self.socket_states) - + WireFormat::len(&self.address_of_largest) - + WireFormat::len(&self.cmdline) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.pid, buf); - WireFormat::write(&self.recv_queued, buf); - WireFormat::write(&self.send_queued, buf); - WireFormat::write(&self.socket_types, buf); - WireFormat::write(&self.socket_states, buf); - WireFormat::write(&self.address_of_largest, buf); - WireFormat::write(&self.cmdline, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxProcessSocketQueues { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - pid: WireFormat::parse_unchecked(buf), - recv_queued: WireFormat::parse_unchecked(buf), - send_queued: WireFormat::parse_unchecked(buf), - socket_types: WireFormat::parse_unchecked(buf), - socket_states: WireFormat::parse_unchecked(buf), - address_of_largest: WireFormat::parse_unchecked(buf), - cmdline: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxProcessSocketQueues { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + + WireFormat::len(&self.pid) + + WireFormat::len(&self.recv_queued) + + WireFormat::len(&self.send_queued) + + WireFormat::len(&self.socket_types) + + WireFormat::len(&self.socket_states) + + WireFormat::len(&self.address_of_largest) + + WireFormat::len(&self.cmdline) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.pid, buf); + WireFormat::write(&self.recv_queued, buf); + WireFormat::write(&self.send_queued, buf); + WireFormat::write(&self.socket_types, buf); + WireFormat::write(&self.socket_states, buf); + WireFormat::write(&self.address_of_largest, buf); + WireFormat::write(&self.cmdline, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxProcessSocketQueues { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + pid: WireFormat::parse_unchecked(buf), + recv_queued: WireFormat::parse_unchecked(buf), + send_queued: WireFormat::parse_unchecked(buf), + socket_types: WireFormat::parse_unchecked(buf), + socket_states: WireFormat::parse_unchecked(buf), + address_of_largest: WireFormat::parse_unchecked(buf), + cmdline: WireFormat::parse_unchecked(buf), + } } } } -/// Summary of socket usage across the system -/// -/// Summaries the socket usage across the system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxSocketUsage { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// average socket queue depths across all sockets on the system - #[cfg_attr(feature = "serde", serde(rename(serialize = "avg_queue_depth")))] - pub avg_queue_depth: u32, - /// the max queue depth seen within the reporting period - #[cfg_attr(feature = "serde", serde(rename(serialize = "max_queue_depth")))] - pub max_queue_depth: u32, - /// A count for each socket type reported in the `socket_types_reported` - /// field, the first entry corresponds to the first enabled bit in - /// `types_reported`. - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_state_counts")))] - pub socket_state_counts: [u16; 16], - /// A count for each socket type reported in the `socket_types_reported` - /// field, the first entry corresponds to the first enabled bit in - /// `types_reported`. - #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_type_counts")))] - pub socket_type_counts: [u16; 16], -} +pub mod msg_linux_socket_usage { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxSocketUsage { - const MESSAGE_TYPE: u16 = 32517; - const MESSAGE_NAME: &'static str = "MSG_LINUX_SOCKET_USAGE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxSocketUsage { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Summary of socket usage across the system + /// + /// Summaries the socket usage across the system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxSocketUsage { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// average socket queue depths across all sockets on the system + #[cfg_attr(feature = "serde", serde(rename(serialize = "avg_queue_depth")))] + pub avg_queue_depth: u32, + /// the max queue depth seen within the reporting period + #[cfg_attr(feature = "serde", serde(rename(serialize = "max_queue_depth")))] + pub max_queue_depth: u32, + /// A count for each socket type reported in the `socket_types_reported` + /// field, the first entry corresponds to the first enabled bit in + /// `types_reported`. + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_state_counts")))] + pub socket_state_counts: [u16; 16], + /// A count for each socket type reported in the `socket_types_reported` + /// field, the first entry corresponds to the first enabled bit in + /// `types_reported`. + #[cfg_attr(feature = "serde", serde(rename(serialize = "socket_type_counts")))] + pub socket_type_counts: [u16; 16], } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxSocketUsage { + const MESSAGE_TYPE: u16 = 32517; + const MESSAGE_NAME: &'static str = "MSG_LINUX_SOCKET_USAGE"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxSocketUsage { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxSocketUsage { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxSocketUsage(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxSocketUsage { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxSocketUsage(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxSocketUsage { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + <[u16; 16] as WireFormat>::MIN_LEN - + <[u16; 16] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.avg_queue_depth) - + WireFormat::len(&self.max_queue_depth) - + WireFormat::len(&self.socket_state_counts) - + WireFormat::len(&self.socket_type_counts) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.avg_queue_depth, buf); - WireFormat::write(&self.max_queue_depth, buf); - WireFormat::write(&self.socket_state_counts, buf); - WireFormat::write(&self.socket_type_counts, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxSocketUsage { - sender_id: None, - avg_queue_depth: WireFormat::parse_unchecked(buf), - max_queue_depth: WireFormat::parse_unchecked(buf), - socket_state_counts: WireFormat::parse_unchecked(buf), - socket_type_counts: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxSocketUsage { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + <[u16; 16] as WireFormat>::MIN_LEN + + <[u16; 16] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.avg_queue_depth) + + WireFormat::len(&self.max_queue_depth) + + WireFormat::len(&self.socket_state_counts) + + WireFormat::len(&self.socket_type_counts) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.avg_queue_depth, buf); + WireFormat::write(&self.max_queue_depth, buf); + WireFormat::write(&self.socket_state_counts, buf); + WireFormat::write(&self.socket_type_counts, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxSocketUsage { + sender_id: None, + avg_queue_depth: WireFormat::parse_unchecked(buf), + max_queue_depth: WireFormat::parse_unchecked(buf), + socket_state_counts: WireFormat::parse_unchecked(buf), + socket_type_counts: WireFormat::parse_unchecked(buf), + } } } } -/// CPU, Memory and Process Starts/Stops -/// -/// This presents a summary of CPU and memory utilization, including a -/// timestamp. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxSysState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// total system memory, in MiB - #[cfg_attr(feature = "serde", serde(rename(serialize = "mem_total")))] - pub mem_total: u16, - /// percent of CPU used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] - pub pcpu: u8, - /// percent of memory used, expressed as a fraction of 256 - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] - pub pmem: u8, - /// number of processes that started during collection phase - #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_starting")))] - pub procs_starting: u16, - /// number of processes that stopped during collection phase - #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_stopping")))] - pub procs_stopping: u16, - /// the count of processes on the system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid_count")))] - pub pid_count: u16, - /// timestamp of message, refer to flags field for how to interpret - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u32, - /// flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_linux_sys_state { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLinuxSysState { - const MESSAGE_TYPE: u16 = 32522; - const MESSAGE_NAME: &'static str = "MSG_LINUX_SYS_STATE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLinuxSysState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// CPU, Memory and Process Starts/Stops + /// + /// This presents a summary of CPU and memory utilization, including a + /// timestamp. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxSysState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// total system memory, in MiB + #[cfg_attr(feature = "serde", serde(rename(serialize = "mem_total")))] + pub mem_total: u16, + /// percent of CPU used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] + pub pcpu: u8, + /// percent of memory used, expressed as a fraction of 256 + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] + pub pmem: u8, + /// number of processes that started during collection phase + #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_starting")))] + pub procs_starting: u16, + /// number of processes that stopped during collection phase + #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_stopping")))] + pub procs_stopping: u16, + /// the count of processes on the system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid_count")))] + pub pid_count: u16, + /// timestamp of message, refer to flags field for how to interpret + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u32, + /// flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn sender_id(&self) -> Option { - self.sender_id + + impl MsgLinuxSysState { + /// Gets the [TimestampType][self::TimestampType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimestampType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimestampType` were added. + pub fn timestamp_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimestampType][TimestampType] of the `flags` bitfield. + pub fn set_timestamp_type(&mut self, timestamp_type: TimestampType) { + set_bit_range!(&mut self.flags, timestamp_type, u8, u8, 2, 0); + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxSysState { + const MESSAGE_TYPE: u16 = 32522; + const MESSAGE_NAME: &'static str = "MSG_LINUX_SYS_STATE"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxSysState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxSysState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxSysState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxSysState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxSysState(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxSysState { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mem_total) - + WireFormat::len(&self.pcpu) - + WireFormat::len(&self.pmem) - + WireFormat::len(&self.procs_starting) - + WireFormat::len(&self.procs_stopping) - + WireFormat::len(&self.pid_count) - + WireFormat::len(&self.time) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mem_total, buf); - WireFormat::write(&self.pcpu, buf); - WireFormat::write(&self.pmem, buf); - WireFormat::write(&self.procs_starting, buf); - WireFormat::write(&self.procs_stopping, buf); - WireFormat::write(&self.pid_count, buf); - WireFormat::write(&self.time, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxSysState { - sender_id: None, - mem_total: WireFormat::parse_unchecked(buf), - pcpu: WireFormat::parse_unchecked(buf), - pmem: WireFormat::parse_unchecked(buf), - procs_starting: WireFormat::parse_unchecked(buf), - procs_stopping: WireFormat::parse_unchecked(buf), - pid_count: WireFormat::parse_unchecked(buf), - time: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxSysState { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mem_total) + + WireFormat::len(&self.pcpu) + + WireFormat::len(&self.pmem) + + WireFormat::len(&self.procs_starting) + + WireFormat::len(&self.procs_stopping) + + WireFormat::len(&self.pid_count) + + WireFormat::len(&self.time) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mem_total, buf); + WireFormat::write(&self.pcpu, buf); + WireFormat::write(&self.pmem, buf); + WireFormat::write(&self.procs_starting, buf); + WireFormat::write(&self.procs_stopping, buf); + WireFormat::write(&self.pid_count, buf); + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxSysState { + sender_id: None, + mem_total: WireFormat::parse_unchecked(buf), + pcpu: WireFormat::parse_unchecked(buf), + pmem: WireFormat::parse_unchecked(buf), + procs_starting: WireFormat::parse_unchecked(buf), + procs_stopping: WireFormat::parse_unchecked(buf), + pid_count: WireFormat::parse_unchecked(buf), + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// CPU, Memory and Process Starts/Stops. DEPRECATED -/// -/// This presents a summary of CPU and memory utilization. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLinuxSysStateDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// total system memory - #[cfg_attr(feature = "serde", serde(rename(serialize = "mem_total")))] - pub mem_total: u16, - /// percent of total cpu currently utilized - #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] - pub pcpu: u8, - /// percent of total memory currently utilized - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] - pub pmem: u8, - /// number of processes that started during collection phase - #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_starting")))] - pub procs_starting: u16, - /// number of processes that stopped during collection phase - #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_stopping")))] - pub procs_stopping: u16, - /// the count of processes on the system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pid_count")))] - pub pid_count: u16, -} + /// timestamp type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimestampType { + /// System time in seconds + SystemTimeInSeconds = 0, -impl ConcreteMessage for MsgLinuxSysStateDepA { - const MESSAGE_TYPE: u16 = 32514; - const MESSAGE_NAME: &'static str = "MSG_LINUX_SYS_STATE_DEP_A"; -} + /// GPS TOW in milliseconds + GpsTowInMilliseconds = 1, + } -impl SbpMessage for MsgLinuxSysStateDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for TimestampType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimestampType::SystemTimeInSeconds => f.write_str("System time in seconds"), + TimestampType::GpsTowInMilliseconds => f.write_str("GPS TOW in milliseconds"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for TimestampType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimestampType::SystemTimeInSeconds), + 1 => Ok(TimestampType::GpsTowInMilliseconds), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id +} + +pub mod msg_linux_sys_state_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// CPU, Memory and Process Starts/Stops. DEPRECATED + /// + /// This presents a summary of CPU and memory utilization. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLinuxSysStateDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// total system memory + #[cfg_attr(feature = "serde", serde(rename(serialize = "mem_total")))] + pub mem_total: u16, + /// percent of total cpu currently utilized + #[cfg_attr(feature = "serde", serde(rename(serialize = "pcpu")))] + pub pcpu: u8, + /// percent of total memory currently utilized + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmem")))] + pub pmem: u8, + /// number of processes that started during collection phase + #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_starting")))] + pub procs_starting: u16, + /// number of processes that stopped during collection phase + #[cfg_attr(feature = "serde", serde(rename(serialize = "procs_stopping")))] + pub procs_stopping: u16, + /// the count of processes on the system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pid_count")))] + pub pid_count: u16, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgLinuxSysStateDepA { + const MESSAGE_TYPE: u16 = 32514; + const MESSAGE_NAME: &'static str = "MSG_LINUX_SYS_STATE_DEP_A"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgLinuxSysStateDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgLinuxSysStateDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLinuxSysStateDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgLinuxSysStateDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLinuxSysStateDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgLinuxSysStateDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mem_total) - + WireFormat::len(&self.pcpu) - + WireFormat::len(&self.pmem) - + WireFormat::len(&self.procs_starting) - + WireFormat::len(&self.procs_stopping) - + WireFormat::len(&self.pid_count) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mem_total, buf); - WireFormat::write(&self.pcpu, buf); - WireFormat::write(&self.pmem, buf); - WireFormat::write(&self.procs_starting, buf); - WireFormat::write(&self.procs_stopping, buf); - WireFormat::write(&self.pid_count, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLinuxSysStateDepA { - sender_id: None, - mem_total: WireFormat::parse_unchecked(buf), - pcpu: WireFormat::parse_unchecked(buf), - pmem: WireFormat::parse_unchecked(buf), - procs_starting: WireFormat::parse_unchecked(buf), - procs_stopping: WireFormat::parse_unchecked(buf), - pid_count: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgLinuxSysStateDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mem_total) + + WireFormat::len(&self.pcpu) + + WireFormat::len(&self.pmem) + + WireFormat::len(&self.procs_starting) + + WireFormat::len(&self.procs_stopping) + + WireFormat::len(&self.pid_count) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mem_total, buf); + WireFormat::write(&self.pcpu, buf); + WireFormat::write(&self.pmem, buf); + WireFormat::write(&self.procs_starting, buf); + WireFormat::write(&self.procs_stopping, buf); + WireFormat::write(&self.pid_count, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLinuxSysStateDepA { + sender_id: None, + mem_total: WireFormat::parse_unchecked(buf), + pcpu: WireFormat::parse_unchecked(buf), + pmem: WireFormat::parse_unchecked(buf), + procs_starting: WireFormat::parse_unchecked(buf), + procs_stopping: WireFormat::parse_unchecked(buf), + pid_count: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/logging.rs b/rust/sbp/src/messages/logging.rs index 59c13e07b1..829c1cf07c 100644 --- a/rust/sbp/src/messages/logging.rs +++ b/rust/sbp/src/messages/logging.rs @@ -13,226 +13,324 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Logging and debugging messages from the device. +pub use msg_fwd::MsgFwd; +pub use msg_log::MsgLog; +pub use msg_print_dep::MsgPrintDep; -use super::lib::*; - -/// Wrapper for FWD a separate stream of information over SBP -/// -/// This message provides the ability to forward messages over SBP. This may -/// take the form of wrapping up SBP messages received by Piksi for logging -/// purposes or wrapping another protocol with SBP. -/// -/// The source identifier indicates from what interface a forwarded stream -/// derived. The protocol identifier identifies what the expected protocol the -/// forwarded msg contains. Protocol 0 represents SBP and the remaining values -/// are implementation defined. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFwd { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// source identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] - pub source: u8, - /// protocol identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "protocol")))] - pub protocol: u8, - /// variable length wrapped binary message - #[cfg_attr(feature = "serde", serde(rename(serialize = "fwd_payload")))] - pub fwd_payload: Vec, -} +pub mod msg_fwd { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFwd { - const MESSAGE_TYPE: u16 = 1026; - const MESSAGE_NAME: &'static str = "MSG_FWD"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFwd { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Wrapper for FWD a separate stream of information over SBP + /// + /// This message provides the ability to forward messages over SBP. This may + /// take the form of wrapping up SBP messages received by Piksi for logging + /// purposes or wrapping another protocol with SBP. + /// + /// The source identifier indicates from what interface a forwarded stream + /// derived. The protocol identifier identifies what the expected protocol the + /// forwarded msg contains. Protocol 0 represents SBP and the remaining values + /// are implementation defined. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFwd { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// source identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] + pub source: u8, + /// protocol identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "protocol")))] + pub protocol: u8, + /// variable length wrapped binary message + #[cfg_attr(feature = "serde", serde(rename(serialize = "fwd_payload")))] + pub fwd_payload: Vec, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgFwd { + const MESSAGE_TYPE: u16 = 1026; + const MESSAGE_NAME: &'static str = "MSG_FWD"; } -} -impl TryFrom for MsgFwd { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFwd(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgFwd { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFwd { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.source) - + WireFormat::len(&self.protocol) - + WireFormat::len(&self.fwd_payload) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.source, buf); - WireFormat::write(&self.protocol, buf); - WireFormat::write(&self.fwd_payload, buf); + impl TryFrom for MsgFwd { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFwd(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFwd { - sender_id: None, - source: WireFormat::parse_unchecked(buf), - protocol: WireFormat::parse_unchecked(buf), - fwd_payload: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgFwd { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.source) + + WireFormat::len(&self.protocol) + + WireFormat::len(&self.fwd_payload) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.source, buf); + WireFormat::write(&self.protocol, buf); + WireFormat::write(&self.fwd_payload, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFwd { + sender_id: None, + source: WireFormat::parse_unchecked(buf), + protocol: WireFormat::parse_unchecked(buf), + fwd_payload: WireFormat::parse_unchecked(buf), + } } } } -/// Plaintext logging messages with levels -/// -/// This message contains a human-readable payload string from the device -/// containing errors, warnings and informational messages at ERROR, WARNING, -/// DEBUG, INFO logging levels. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgLog { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Logging level - #[cfg_attr(feature = "serde", serde(rename(serialize = "level")))] - pub level: u8, - /// Human-readable string - #[cfg_attr(feature = "serde", serde(rename(serialize = "text")))] - pub text: SbpString, Unterminated>, -} +pub mod msg_log { + #![allow(unused_imports)] -impl ConcreteMessage for MsgLog { - const MESSAGE_TYPE: u16 = 1025; - const MESSAGE_NAME: &'static str = "MSG_LOG"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgLog { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Plaintext logging messages with levels + /// + /// This message contains a human-readable payload string from the device + /// containing errors, warnings and informational messages at ERROR, WARNING, + /// DEBUG, INFO logging levels. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgLog { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Logging level + #[cfg_attr(feature = "serde", serde(rename(serialize = "level")))] + pub level: u8, + /// Human-readable string + #[cfg_attr(feature = "serde", serde(rename(serialize = "text")))] + pub text: SbpString, Unterminated>, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgLog { + /// Gets the [LoggingLevel][self::LoggingLevel] stored in the `level` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `LoggingLevel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `LoggingLevel` were added. + pub fn logging_level(&self) -> Result { + get_bit_range!(self.level, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [LoggingLevel][LoggingLevel] of the `level` bitfield. + pub fn set_logging_level(&mut self, logging_level: LoggingLevel) { + set_bit_range!(&mut self.level, logging_level, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgLog { + const MESSAGE_TYPE: u16 = 1025; + const MESSAGE_NAME: &'static str = "MSG_LOG"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgLog { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgLog { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgLog(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgLog { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgLog(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgLog { + const MIN_LEN: usize = + ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.level) + WireFormat::len(&self.text) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.level, buf); + WireFormat::write(&self.text, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgLog { + sender_id: None, + level: WireFormat::parse_unchecked(buf), + text: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgLog { - const MIN_LEN: usize = - ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.level) + WireFormat::len(&self.text) + /// Logging level + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum LoggingLevel { + /// EMERG + EMERG = 0, + + /// ALERT + ALERT = 1, + + /// CRIT + CRIT = 2, + + /// ERROR + ERROR = 3, + + /// WARN + WARN = 4, + + /// NOTICE + NOTICE = 5, + + /// INFO + INFO = 6, + + /// DEBUG + DEBUG = 7, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.level, buf); - WireFormat::write(&self.text, buf); + + impl std::fmt::Display for LoggingLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LoggingLevel::EMERG => f.write_str("EMERG"), + LoggingLevel::ALERT => f.write_str("ALERT"), + LoggingLevel::CRIT => f.write_str("CRIT"), + LoggingLevel::ERROR => f.write_str("ERROR"), + LoggingLevel::WARN => f.write_str("WARN"), + LoggingLevel::NOTICE => f.write_str("NOTICE"), + LoggingLevel::INFO => f.write_str("INFO"), + LoggingLevel::DEBUG => f.write_str("DEBUG"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgLog { - sender_id: None, - level: WireFormat::parse_unchecked(buf), - text: WireFormat::parse_unchecked(buf), + + impl TryFrom for LoggingLevel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(LoggingLevel::EMERG), + 1 => Ok(LoggingLevel::ALERT), + 2 => Ok(LoggingLevel::CRIT), + 3 => Ok(LoggingLevel::ERROR), + 4 => Ok(LoggingLevel::WARN), + 5 => Ok(LoggingLevel::NOTICE), + 6 => Ok(LoggingLevel::INFO), + 7 => Ok(LoggingLevel::DEBUG), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPrintDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Human-readable string - #[cfg_attr(feature = "serde", serde(rename(serialize = "text")))] - pub text: SbpString, Unterminated>, -} +pub mod msg_print_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgPrintDep { - const MESSAGE_TYPE: u16 = 16; - const MESSAGE_NAME: &'static str = "MSG_PRINT_DEP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgPrintDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPrintDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Human-readable string + #[cfg_attr(feature = "serde", serde(rename(serialize = "text")))] + pub text: SbpString, Unterminated>, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgPrintDep { + const MESSAGE_TYPE: u16 = 16; + const MESSAGE_NAME: &'static str = "MSG_PRINT_DEP"; } -} -impl TryFrom for MsgPrintDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPrintDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgPrintDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgPrintDep { - const MIN_LEN: usize = , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.text) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.text, buf); + impl TryFrom for MsgPrintDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPrintDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPrintDep { - sender_id: None, - text: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgPrintDep { + const MIN_LEN: usize = , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.text) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.text, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPrintDep { + sender_id: None, + text: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/mag.rs b/rust/sbp/src/messages/mag.rs index 485f6b8c9c..af16b4c4d8 100644 --- a/rust/sbp/src/messages/mag.rs +++ b/rust/sbp/src/messages/mag.rs @@ -13,107 +13,113 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Magnetometer (mag) messages. +pub use msg_mag_raw::MsgMagRaw; -use super::lib::*; +pub mod msg_mag_raw { + #![allow(unused_imports)] -/// Raw magnetometer data -/// -/// Raw data from the magnetometer. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgMagRaw { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Milliseconds since start of GPS week. If the high bit is set, the time - /// is unknown or invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Milliseconds since start of GPS week, fractional part - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_f")))] - pub tow_f: u8, - /// Magnetic field in the body frame X axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_x")))] - pub mag_x: i16, - /// Magnetic field in the body frame Y axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_y")))] - pub mag_y: i16, - /// Magnetic field in the body frame Z axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_z")))] - pub mag_z: i16, -} - -impl ConcreteMessage for MsgMagRaw { - const MESSAGE_TYPE: u16 = 2306; - const MESSAGE_NAME: &'static str = "MSG_MAG_RAW"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgMagRaw { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Raw magnetometer data + /// + /// Raw data from the magnetometer. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgMagRaw { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Milliseconds since start of GPS week. If the high bit is set, the time + /// is unknown or invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Milliseconds since start of GPS week, fractional part + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_f")))] + pub tow_f: u8, + /// Magnetic field in the body frame X axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_x")))] + pub mag_x: i16, + /// Magnetic field in the body frame Y axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_y")))] + pub mag_y: i16, + /// Magnetic field in the body frame Z axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "mag_z")))] + pub mag_z: i16, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgMagRaw { + const MESSAGE_TYPE: u16 = 2306; + const MESSAGE_NAME: &'static str = "MSG_MAG_RAW"; } -} -impl TryFrom for MsgMagRaw { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgMagRaw(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgMagRaw { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgMagRaw { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.tow_f) - + WireFormat::len(&self.mag_x) - + WireFormat::len(&self.mag_y) - + WireFormat::len(&self.mag_z) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.tow_f, buf); - WireFormat::write(&self.mag_x, buf); - WireFormat::write(&self.mag_y, buf); - WireFormat::write(&self.mag_z, buf); + impl TryFrom for MsgMagRaw { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgMagRaw(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgMagRaw { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - tow_f: WireFormat::parse_unchecked(buf), - mag_x: WireFormat::parse_unchecked(buf), - mag_y: WireFormat::parse_unchecked(buf), - mag_z: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgMagRaw { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.tow_f) + + WireFormat::len(&self.mag_x) + + WireFormat::len(&self.mag_y) + + WireFormat::len(&self.mag_z) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.tow_f, buf); + WireFormat::write(&self.mag_x, buf); + WireFormat::write(&self.mag_y, buf); + WireFormat::write(&self.mag_z, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgMagRaw { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + tow_f: WireFormat::parse_unchecked(buf), + mag_x: WireFormat::parse_unchecked(buf), + mag_y: WireFormat::parse_unchecked(buf), + mag_z: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/mod.rs b/rust/sbp/src/messages/mod.rs index cb6f6530d3..6d5256c73c 100644 --- a/rust/sbp/src/messages/mod.rs +++ b/rust/sbp/src/messages/mod.rs @@ -32,211 +32,211 @@ pub mod tracking; pub mod unknown; pub mod user; pub mod vehicle; -use self::acquisition::MsgAcqResult; -use self::acquisition::MsgAcqResultDepA; -use self::acquisition::MsgAcqResultDepB; -use self::acquisition::MsgAcqResultDepC; -use self::acquisition::MsgAcqSvProfile; -use self::acquisition::MsgAcqSvProfileDep; -use self::bootload::MsgBootloaderHandshakeDepA; -use self::bootload::MsgBootloaderHandshakeReq; -use self::bootload::MsgBootloaderHandshakeResp; -use self::bootload::MsgBootloaderJumpToApp; -use self::bootload::MsgNapDeviceDnaReq; -use self::bootload::MsgNapDeviceDnaResp; -use self::ext_events::MsgExtEvent; -use self::file_io::MsgFileioConfigReq; -use self::file_io::MsgFileioConfigResp; -use self::file_io::MsgFileioReadDirReq; -use self::file_io::MsgFileioReadDirResp; -use self::file_io::MsgFileioReadReq; -use self::file_io::MsgFileioReadResp; -use self::file_io::MsgFileioRemove; -use self::file_io::MsgFileioWriteReq; -use self::file_io::MsgFileioWriteResp; -use self::flash::MsgFlashDone; -use self::flash::MsgFlashErase; -use self::flash::MsgFlashProgram; -use self::flash::MsgFlashReadReq; -use self::flash::MsgFlashReadResp; -use self::flash::MsgM25FlashWriteStatus; -use self::flash::MsgStmFlashLockSector; -use self::flash::MsgStmFlashUnlockSector; -use self::flash::MsgStmUniqueIdReq; -use self::flash::MsgStmUniqueIdResp; -use self::imu::MsgImuAux; -use self::imu::MsgImuRaw; -use self::linux::MsgLinuxCpuState; -use self::linux::MsgLinuxCpuStateDepA; -use self::linux::MsgLinuxMemState; -use self::linux::MsgLinuxMemStateDepA; -use self::linux::MsgLinuxProcessFdCount; -use self::linux::MsgLinuxProcessFdSummary; -use self::linux::MsgLinuxProcessSocketCounts; -use self::linux::MsgLinuxProcessSocketQueues; -use self::linux::MsgLinuxSocketUsage; -use self::linux::MsgLinuxSysState; -use self::linux::MsgLinuxSysStateDepA; -use self::logging::MsgFwd; -use self::logging::MsgLog; -use self::logging::MsgPrintDep; -use self::mag::MsgMagRaw; -use self::navigation::MsgAgeCorrections; -use self::navigation::MsgBaselineEcef; -use self::navigation::MsgBaselineEcefDepA; -use self::navigation::MsgBaselineHeadingDepA; -use self::navigation::MsgBaselineNed; -use self::navigation::MsgBaselineNedDepA; -use self::navigation::MsgDops; -use self::navigation::MsgDopsDepA; -use self::navigation::MsgGpsTime; -use self::navigation::MsgGpsTimeDepA; -use self::navigation::MsgGpsTimeGnss; -use self::navigation::MsgPosEcef; -use self::navigation::MsgPosEcefCov; -use self::navigation::MsgPosEcefCovGnss; -use self::navigation::MsgPosEcefDepA; -use self::navigation::MsgPosEcefGnss; -use self::navigation::MsgPosLlh; -use self::navigation::MsgPosLlhAcc; -use self::navigation::MsgPosLlhCov; -use self::navigation::MsgPosLlhCovGnss; -use self::navigation::MsgPosLlhDepA; -use self::navigation::MsgPosLlhGnss; -use self::navigation::MsgProtectionLevel; -use self::navigation::MsgProtectionLevelDepA; -use self::navigation::MsgUtcTime; -use self::navigation::MsgUtcTimeGnss; -use self::navigation::MsgVelBody; -use self::navigation::MsgVelCog; -use self::navigation::MsgVelEcef; -use self::navigation::MsgVelEcefCov; -use self::navigation::MsgVelEcefCovGnss; -use self::navigation::MsgVelEcefDepA; -use self::navigation::MsgVelEcefGnss; -use self::navigation::MsgVelNed; -use self::navigation::MsgVelNedCov; -use self::navigation::MsgVelNedCovGnss; -use self::navigation::MsgVelNedDepA; -use self::navigation::MsgVelNedGnss; -use self::ndb::MsgNdbEvent; -use self::observation::MsgAlmanacGlo; -use self::observation::MsgAlmanacGloDep; -use self::observation::MsgAlmanacGps; -use self::observation::MsgAlmanacGpsDep; -use self::observation::MsgBasePosEcef; -use self::observation::MsgBasePosLlh; -use self::observation::MsgEphemerisBds; -use self::observation::MsgEphemerisDepA; -use self::observation::MsgEphemerisDepB; -use self::observation::MsgEphemerisDepC; -use self::observation::MsgEphemerisDepD; -use self::observation::MsgEphemerisGal; -use self::observation::MsgEphemerisGalDepA; -use self::observation::MsgEphemerisGlo; -use self::observation::MsgEphemerisGloDepA; -use self::observation::MsgEphemerisGloDepB; -use self::observation::MsgEphemerisGloDepC; -use self::observation::MsgEphemerisGloDepD; -use self::observation::MsgEphemerisGps; -use self::observation::MsgEphemerisGpsDepE; -use self::observation::MsgEphemerisGpsDepF; -use self::observation::MsgEphemerisQzss; -use self::observation::MsgEphemerisSbas; -use self::observation::MsgEphemerisSbasDepA; -use self::observation::MsgEphemerisSbasDepB; -use self::observation::MsgGloBiases; -use self::observation::MsgGnssCapb; -use self::observation::MsgGroupDelay; -use self::observation::MsgGroupDelayDepA; -use self::observation::MsgGroupDelayDepB; -use self::observation::MsgIono; -use self::observation::MsgObs; -use self::observation::MsgObsDepA; -use self::observation::MsgObsDepB; -use self::observation::MsgObsDepC; -use self::observation::MsgOsr; -use self::observation::MsgSvAzEl; -use self::observation::MsgSvConfigurationGpsDep; -use self::orientation::MsgAngularRate; -use self::orientation::MsgBaselineHeading; -use self::orientation::MsgOrientEuler; -use self::orientation::MsgOrientQuat; -use self::piksi::MsgAlmanac; -use self::piksi::MsgCellModemStatus; -use self::piksi::MsgCommandOutput; -use self::piksi::MsgCommandReq; -use self::piksi::MsgCommandResp; -use self::piksi::MsgCwResults; -use self::piksi::MsgCwStart; -use self::piksi::MsgDeviceMonitor; -use self::piksi::MsgFrontEndGain; -use self::piksi::MsgIarState; -use self::piksi::MsgInitBaseDep; -use self::piksi::MsgMaskSatellite; -use self::piksi::MsgMaskSatelliteDep; -use self::piksi::MsgNetworkBandwidthUsage; -use self::piksi::MsgNetworkStateReq; -use self::piksi::MsgNetworkStateResp; -use self::piksi::MsgReset; -use self::piksi::MsgResetDep; -use self::piksi::MsgResetFilters; -use self::piksi::MsgSetTime; -use self::piksi::MsgSpecan; -use self::piksi::MsgSpecanDep; -use self::piksi::MsgThreadState; -use self::piksi::MsgUartState; -use self::piksi::MsgUartStateDepa; -use self::sbas::MsgSbasRaw; -use self::settings::MsgSettingsReadByIndexDone; -use self::settings::MsgSettingsReadByIndexReq; -use self::settings::MsgSettingsReadByIndexResp; -use self::settings::MsgSettingsReadReq; -use self::settings::MsgSettingsReadResp; -use self::settings::MsgSettingsRegister; -use self::settings::MsgSettingsRegisterResp; -use self::settings::MsgSettingsSave; -use self::settings::MsgSettingsWrite; -use self::settings::MsgSettingsWriteResp; -use self::solution_meta::MsgSolnMeta; -use self::solution_meta::MsgSolnMetaDepA; -use self::ssr::MsgSsrCodeBiases; -use self::ssr::MsgSsrGridDefinitionDepA; -use self::ssr::MsgSsrGriddedCorrection; -use self::ssr::MsgSsrGriddedCorrectionDepA; -use self::ssr::MsgSsrGriddedCorrectionNoStdDepA; -use self::ssr::MsgSsrOrbitClock; -use self::ssr::MsgSsrOrbitClockDepA; -use self::ssr::MsgSsrPhaseBiases; -use self::ssr::MsgSsrSatelliteApc; -use self::ssr::MsgSsrStecCorrection; -use self::ssr::MsgSsrStecCorrectionDepA; -use self::ssr::MsgSsrTileDefinition; -use self::system::MsgCsacTelemetry; -use self::system::MsgCsacTelemetryLabels; -use self::system::MsgDgnssStatus; -use self::system::MsgGnssTimeOffset; -use self::system::MsgGroupMeta; -use self::system::MsgHeartbeat; -use self::system::MsgInsStatus; -use self::system::MsgInsUpdates; -use self::system::MsgPpsTime; -use self::system::MsgSensorAidEvent; -use self::system::MsgStartup; -use self::system::MsgStatusReport; -use self::tracking::MsgMeasurementState; -use self::tracking::MsgTrackingIq; -use self::tracking::MsgTrackingIqDepA; -use self::tracking::MsgTrackingIqDepB; -use self::tracking::MsgTrackingState; -use self::tracking::MsgTrackingStateDepA; -use self::tracking::MsgTrackingStateDepB; -use self::tracking::MsgTrackingStateDetailedDep; -use self::tracking::MsgTrackingStateDetailedDepA; +use self::acquisition::msg_acq_result::MsgAcqResult; +use self::acquisition::msg_acq_result_dep_a::MsgAcqResultDepA; +use self::acquisition::msg_acq_result_dep_b::MsgAcqResultDepB; +use self::acquisition::msg_acq_result_dep_c::MsgAcqResultDepC; +use self::acquisition::msg_acq_sv_profile::MsgAcqSvProfile; +use self::acquisition::msg_acq_sv_profile_dep::MsgAcqSvProfileDep; +use self::bootload::msg_bootloader_handshake_dep_a::MsgBootloaderHandshakeDepA; +use self::bootload::msg_bootloader_handshake_req::MsgBootloaderHandshakeReq; +use self::bootload::msg_bootloader_handshake_resp::MsgBootloaderHandshakeResp; +use self::bootload::msg_bootloader_jump_to_app::MsgBootloaderJumpToApp; +use self::bootload::msg_nap_device_dna_req::MsgNapDeviceDnaReq; +use self::bootload::msg_nap_device_dna_resp::MsgNapDeviceDnaResp; +use self::ext_events::msg_ext_event::MsgExtEvent; +use self::file_io::msg_fileio_config_req::MsgFileioConfigReq; +use self::file_io::msg_fileio_config_resp::MsgFileioConfigResp; +use self::file_io::msg_fileio_read_dir_req::MsgFileioReadDirReq; +use self::file_io::msg_fileio_read_dir_resp::MsgFileioReadDirResp; +use self::file_io::msg_fileio_read_req::MsgFileioReadReq; +use self::file_io::msg_fileio_read_resp::MsgFileioReadResp; +use self::file_io::msg_fileio_remove::MsgFileioRemove; +use self::file_io::msg_fileio_write_req::MsgFileioWriteReq; +use self::file_io::msg_fileio_write_resp::MsgFileioWriteResp; +use self::flash::msg_flash_done::MsgFlashDone; +use self::flash::msg_flash_erase::MsgFlashErase; +use self::flash::msg_flash_program::MsgFlashProgram; +use self::flash::msg_flash_read_req::MsgFlashReadReq; +use self::flash::msg_flash_read_resp::MsgFlashReadResp; +use self::flash::msg_m25_flash_write_status::MsgM25FlashWriteStatus; +use self::flash::msg_stm_flash_lock_sector::MsgStmFlashLockSector; +use self::flash::msg_stm_flash_unlock_sector::MsgStmFlashUnlockSector; +use self::flash::msg_stm_unique_id_req::MsgStmUniqueIdReq; +use self::flash::msg_stm_unique_id_resp::MsgStmUniqueIdResp; +use self::imu::msg_imu_aux::MsgImuAux; +use self::imu::msg_imu_raw::MsgImuRaw; +use self::linux::msg_linux_cpu_state::MsgLinuxCpuState; +use self::linux::msg_linux_cpu_state_dep_a::MsgLinuxCpuStateDepA; +use self::linux::msg_linux_mem_state::MsgLinuxMemState; +use self::linux::msg_linux_mem_state_dep_a::MsgLinuxMemStateDepA; +use self::linux::msg_linux_process_fd_count::MsgLinuxProcessFdCount; +use self::linux::msg_linux_process_fd_summary::MsgLinuxProcessFdSummary; +use self::linux::msg_linux_process_socket_counts::MsgLinuxProcessSocketCounts; +use self::linux::msg_linux_process_socket_queues::MsgLinuxProcessSocketQueues; +use self::linux::msg_linux_socket_usage::MsgLinuxSocketUsage; +use self::linux::msg_linux_sys_state::MsgLinuxSysState; +use self::linux::msg_linux_sys_state_dep_a::MsgLinuxSysStateDepA; +use self::logging::msg_fwd::MsgFwd; +use self::logging::msg_log::MsgLog; +use self::logging::msg_print_dep::MsgPrintDep; +use self::mag::msg_mag_raw::MsgMagRaw; +use self::navigation::msg_age_corrections::MsgAgeCorrections; +use self::navigation::msg_baseline_ecef::MsgBaselineEcef; +use self::navigation::msg_baseline_ecef_dep_a::MsgBaselineEcefDepA; +use self::navigation::msg_baseline_heading_dep_a::MsgBaselineHeadingDepA; +use self::navigation::msg_baseline_ned::MsgBaselineNed; +use self::navigation::msg_baseline_ned_dep_a::MsgBaselineNedDepA; +use self::navigation::msg_dops::MsgDops; +use self::navigation::msg_dops_dep_a::MsgDopsDepA; +use self::navigation::msg_gps_time::MsgGpsTime; +use self::navigation::msg_gps_time_dep_a::MsgGpsTimeDepA; +use self::navigation::msg_gps_time_gnss::MsgGpsTimeGnss; +use self::navigation::msg_pos_ecef::MsgPosEcef; +use self::navigation::msg_pos_ecef_cov::MsgPosEcefCov; +use self::navigation::msg_pos_ecef_cov_gnss::MsgPosEcefCovGnss; +use self::navigation::msg_pos_ecef_dep_a::MsgPosEcefDepA; +use self::navigation::msg_pos_ecef_gnss::MsgPosEcefGnss; +use self::navigation::msg_pos_llh::MsgPosLlh; +use self::navigation::msg_pos_llh_acc::MsgPosLlhAcc; +use self::navigation::msg_pos_llh_cov::MsgPosLlhCov; +use self::navigation::msg_pos_llh_cov_gnss::MsgPosLlhCovGnss; +use self::navigation::msg_pos_llh_dep_a::MsgPosLlhDepA; +use self::navigation::msg_pos_llh_gnss::MsgPosLlhGnss; +use self::navigation::msg_protection_level::MsgProtectionLevel; +use self::navigation::msg_protection_level_dep_a::MsgProtectionLevelDepA; +use self::navigation::msg_utc_time::MsgUtcTime; +use self::navigation::msg_utc_time_gnss::MsgUtcTimeGnss; +use self::navigation::msg_vel_body::MsgVelBody; +use self::navigation::msg_vel_cog::MsgVelCog; +use self::navigation::msg_vel_ecef::MsgVelEcef; +use self::navigation::msg_vel_ecef_cov::MsgVelEcefCov; +use self::navigation::msg_vel_ecef_cov_gnss::MsgVelEcefCovGnss; +use self::navigation::msg_vel_ecef_dep_a::MsgVelEcefDepA; +use self::navigation::msg_vel_ecef_gnss::MsgVelEcefGnss; +use self::navigation::msg_vel_ned::MsgVelNed; +use self::navigation::msg_vel_ned_cov::MsgVelNedCov; +use self::navigation::msg_vel_ned_cov_gnss::MsgVelNedCovGnss; +use self::navigation::msg_vel_ned_dep_a::MsgVelNedDepA; +use self::navigation::msg_vel_ned_gnss::MsgVelNedGnss; +use self::ndb::msg_ndb_event::MsgNdbEvent; +use self::observation::msg_almanac_glo::MsgAlmanacGlo; +use self::observation::msg_almanac_glo_dep::MsgAlmanacGloDep; +use self::observation::msg_almanac_gps::MsgAlmanacGps; +use self::observation::msg_almanac_gps_dep::MsgAlmanacGpsDep; +use self::observation::msg_base_pos_ecef::MsgBasePosEcef; +use self::observation::msg_base_pos_llh::MsgBasePosLlh; +use self::observation::msg_ephemeris_bds::MsgEphemerisBds; +use self::observation::msg_ephemeris_dep_a::MsgEphemerisDepA; +use self::observation::msg_ephemeris_dep_b::MsgEphemerisDepB; +use self::observation::msg_ephemeris_dep_c::MsgEphemerisDepC; +use self::observation::msg_ephemeris_dep_d::MsgEphemerisDepD; +use self::observation::msg_ephemeris_gal::MsgEphemerisGal; +use self::observation::msg_ephemeris_gal_dep_a::MsgEphemerisGalDepA; +use self::observation::msg_ephemeris_glo::MsgEphemerisGlo; +use self::observation::msg_ephemeris_glo_dep_a::MsgEphemerisGloDepA; +use self::observation::msg_ephemeris_glo_dep_b::MsgEphemerisGloDepB; +use self::observation::msg_ephemeris_glo_dep_c::MsgEphemerisGloDepC; +use self::observation::msg_ephemeris_glo_dep_d::MsgEphemerisGloDepD; +use self::observation::msg_ephemeris_gps::MsgEphemerisGps; +use self::observation::msg_ephemeris_gps_dep_e::MsgEphemerisGpsDepE; +use self::observation::msg_ephemeris_gps_dep_f::MsgEphemerisGpsDepF; +use self::observation::msg_ephemeris_qzss::MsgEphemerisQzss; +use self::observation::msg_ephemeris_sbas::MsgEphemerisSbas; +use self::observation::msg_ephemeris_sbas_dep_a::MsgEphemerisSbasDepA; +use self::observation::msg_ephemeris_sbas_dep_b::MsgEphemerisSbasDepB; +use self::observation::msg_glo_biases::MsgGloBiases; +use self::observation::msg_gnss_capb::MsgGnssCapb; +use self::observation::msg_group_delay::MsgGroupDelay; +use self::observation::msg_group_delay_dep_a::MsgGroupDelayDepA; +use self::observation::msg_group_delay_dep_b::MsgGroupDelayDepB; +use self::observation::msg_iono::MsgIono; +use self::observation::msg_obs::MsgObs; +use self::observation::msg_obs_dep_a::MsgObsDepA; +use self::observation::msg_obs_dep_b::MsgObsDepB; +use self::observation::msg_obs_dep_c::MsgObsDepC; +use self::observation::msg_osr::MsgOsr; +use self::observation::msg_sv_az_el::MsgSvAzEl; +use self::observation::msg_sv_configuration_gps_dep::MsgSvConfigurationGpsDep; +use self::orientation::msg_angular_rate::MsgAngularRate; +use self::orientation::msg_baseline_heading::MsgBaselineHeading; +use self::orientation::msg_orient_euler::MsgOrientEuler; +use self::orientation::msg_orient_quat::MsgOrientQuat; +use self::piksi::msg_almanac::MsgAlmanac; +use self::piksi::msg_cell_modem_status::MsgCellModemStatus; +use self::piksi::msg_command_output::MsgCommandOutput; +use self::piksi::msg_command_req::MsgCommandReq; +use self::piksi::msg_command_resp::MsgCommandResp; +use self::piksi::msg_cw_results::MsgCwResults; +use self::piksi::msg_cw_start::MsgCwStart; +use self::piksi::msg_device_monitor::MsgDeviceMonitor; +use self::piksi::msg_front_end_gain::MsgFrontEndGain; +use self::piksi::msg_iar_state::MsgIarState; +use self::piksi::msg_init_base_dep::MsgInitBaseDep; +use self::piksi::msg_mask_satellite::MsgMaskSatellite; +use self::piksi::msg_mask_satellite_dep::MsgMaskSatelliteDep; +use self::piksi::msg_network_bandwidth_usage::MsgNetworkBandwidthUsage; +use self::piksi::msg_network_state_req::MsgNetworkStateReq; +use self::piksi::msg_network_state_resp::MsgNetworkStateResp; +use self::piksi::msg_reset::MsgReset; +use self::piksi::msg_reset_dep::MsgResetDep; +use self::piksi::msg_reset_filters::MsgResetFilters; +use self::piksi::msg_set_time::MsgSetTime; +use self::piksi::msg_specan::MsgSpecan; +use self::piksi::msg_specan_dep::MsgSpecanDep; +use self::piksi::msg_thread_state::MsgThreadState; +use self::piksi::msg_uart_state::MsgUartState; +use self::piksi::msg_uart_state_depa::MsgUartStateDepa; +use self::sbas::msg_sbas_raw::MsgSbasRaw; +use self::settings::msg_settings_read_by_index_done::MsgSettingsReadByIndexDone; +use self::settings::msg_settings_read_by_index_req::MsgSettingsReadByIndexReq; +use self::settings::msg_settings_read_by_index_resp::MsgSettingsReadByIndexResp; +use self::settings::msg_settings_read_req::MsgSettingsReadReq; +use self::settings::msg_settings_read_resp::MsgSettingsReadResp; +use self::settings::msg_settings_register::MsgSettingsRegister; +use self::settings::msg_settings_register_resp::MsgSettingsRegisterResp; +use self::settings::msg_settings_save::MsgSettingsSave; +use self::settings::msg_settings_write::MsgSettingsWrite; +use self::settings::msg_settings_write_resp::MsgSettingsWriteResp; +use self::solution_meta::msg_soln_meta::MsgSolnMeta; +use self::solution_meta::msg_soln_meta_dep_a::MsgSolnMetaDepA; +use self::ssr::msg_ssr_code_biases::MsgSsrCodeBiases; +use self::ssr::msg_ssr_grid_definition_dep_a::MsgSsrGridDefinitionDepA; +use self::ssr::msg_ssr_gridded_correction::MsgSsrGriddedCorrection; +use self::ssr::msg_ssr_gridded_correction_dep_a::MsgSsrGriddedCorrectionDepA; +use self::ssr::msg_ssr_gridded_correction_no_std_dep_a::MsgSsrGriddedCorrectionNoStdDepA; +use self::ssr::msg_ssr_orbit_clock::MsgSsrOrbitClock; +use self::ssr::msg_ssr_orbit_clock_dep_a::MsgSsrOrbitClockDepA; +use self::ssr::msg_ssr_phase_biases::MsgSsrPhaseBiases; +use self::ssr::msg_ssr_satellite_apc::MsgSsrSatelliteApc; +use self::ssr::msg_ssr_stec_correction::MsgSsrStecCorrection; +use self::ssr::msg_ssr_stec_correction_dep_a::MsgSsrStecCorrectionDepA; +use self::ssr::msg_ssr_tile_definition::MsgSsrTileDefinition; +use self::system::msg_csac_telemetry::MsgCsacTelemetry; +use self::system::msg_csac_telemetry_labels::MsgCsacTelemetryLabels; +use self::system::msg_dgnss_status::MsgDgnssStatus; +use self::system::msg_gnss_time_offset::MsgGnssTimeOffset; +use self::system::msg_group_meta::MsgGroupMeta; +use self::system::msg_heartbeat::MsgHeartbeat; +use self::system::msg_ins_status::MsgInsStatus; +use self::system::msg_ins_updates::MsgInsUpdates; +use self::system::msg_pps_time::MsgPpsTime; +use self::system::msg_sensor_aid_event::MsgSensorAidEvent; +use self::system::msg_startup::MsgStartup; +use self::system::msg_status_report::MsgStatusReport; +use self::tracking::msg_measurement_state::MsgMeasurementState; +use self::tracking::msg_tracking_iq::MsgTrackingIq; +use self::tracking::msg_tracking_iq_dep_a::MsgTrackingIqDepA; +use self::tracking::msg_tracking_iq_dep_b::MsgTrackingIqDepB; +use self::tracking::msg_tracking_state::MsgTrackingState; +use self::tracking::msg_tracking_state_dep_a::MsgTrackingStateDepA; +use self::tracking::msg_tracking_state_dep_b::MsgTrackingStateDepB; +use self::tracking::msg_tracking_state_detailed_dep::MsgTrackingStateDetailedDep; +use self::tracking::msg_tracking_state_detailed_dep_a::MsgTrackingStateDetailedDepA; use self::unknown::Unknown; -use self::user::MsgUserData; -use self::vehicle::MsgOdometry; -use self::vehicle::MsgWheeltick; +use self::user::msg_user_data::MsgUserData; +use self::vehicle::msg_odometry::MsgOdometry; +use self::vehicle::msg_wheeltick::MsgWheeltick; mod lib { //! Common imports so we can just `use super::lib::*` in all the message files @@ -253,6 +253,31 @@ mod lib { pub use super::{ConcreteMessage, Sbp, SbpMessage, TryFromSbpError}; pub use bytes::{Buf, BufMut}; + + macro_rules! get_bit_range { + ($bitrange:expr, $source_ty:ty, $target_ty:ty, $msb:expr, $lsb:expr) => {{ + let source_bit_len = std::mem::size_of::<$source_ty>() * 8; + let target_bit_len = std::mem::size_of::<$target_ty>() * 8; + let result = (($bitrange << (source_bit_len - $msb - 1)) + >> (source_bit_len - $msb - 1 + $lsb)) as $target_ty; + result << (target_bit_len - ($msb - $lsb + 1)) >> (target_bit_len - ($msb - $lsb + 1)) + }}; + } + + macro_rules! set_bit_range { + ($bitrange:expr, $value: expr, $source_ty:ty, $target_ty:ty, $msb:expr, $lsb:expr) => { + let source_bit_len = std::mem::size_of::<$source_ty>() * 8; + let mask: $source_ty = !(0 as $source_ty) + << (source_bit_len - $msb - 1) + >> (source_bit_len - $msb - 1 + $lsb) + << ($lsb); + *$bitrange &= !mask; + *$bitrange |= ($value as $source_ty << $lsb) & mask; + }; + } + + pub(crate) use get_bit_range; + pub(crate) use set_bit_range; } use lib::*; diff --git a/rust/sbp/src/messages/navigation.rs b/rust/sbp/src/messages/navigation.rs index 1eb0421f09..222db5c4ca 100644 --- a/rust/sbp/src/messages/navigation.rs +++ b/rust/sbp/src/messages/navigation.rs @@ -36,5047 +36,9353 @@ //! When this is not the case, the tow may be a time of arrival or a local //! system timestamp, irrespective of the time reference (GPS Week or else), //! but not a Time of Measurement. - -use super::lib::*; - -/// Horizontal estimated error ellipse -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct EstimatedHorizontalErrorEllipse { - /// The semi major axis of the estimated horizontal error ellipse at the - /// user-configured confidence level; zero implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "semi_major")))] - pub semi_major: f32, - /// The semi minor axis of the estimated horizontal error ellipse at the - /// user-configured confidence level; zero implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "semi_minor")))] - pub semi_minor: f32, - /// The orientation of the semi major axis of the estimated horizontal error - /// ellipse with respect to North. - #[cfg_attr(feature = "serde", serde(rename(serialize = "orientation")))] - pub orientation: f32, +pub use estimated_horizontal_error_ellipse::EstimatedHorizontalErrorEllipse; +pub use msg_age_corrections::MsgAgeCorrections; +pub use msg_baseline_ecef::MsgBaselineEcef; +pub use msg_baseline_ecef_dep_a::MsgBaselineEcefDepA; +pub use msg_baseline_heading_dep_a::MsgBaselineHeadingDepA; +pub use msg_baseline_ned::MsgBaselineNed; +pub use msg_baseline_ned_dep_a::MsgBaselineNedDepA; +pub use msg_dops::MsgDops; +pub use msg_dops_dep_a::MsgDopsDepA; +pub use msg_gps_time::MsgGpsTime; +pub use msg_gps_time_dep_a::MsgGpsTimeDepA; +pub use msg_gps_time_gnss::MsgGpsTimeGnss; +pub use msg_pos_ecef::MsgPosEcef; +pub use msg_pos_ecef_cov::MsgPosEcefCov; +pub use msg_pos_ecef_cov_gnss::MsgPosEcefCovGnss; +pub use msg_pos_ecef_dep_a::MsgPosEcefDepA; +pub use msg_pos_ecef_gnss::MsgPosEcefGnss; +pub use msg_pos_llh::MsgPosLlh; +pub use msg_pos_llh_acc::MsgPosLlhAcc; +pub use msg_pos_llh_cov::MsgPosLlhCov; +pub use msg_pos_llh_cov_gnss::MsgPosLlhCovGnss; +pub use msg_pos_llh_dep_a::MsgPosLlhDepA; +pub use msg_pos_llh_gnss::MsgPosLlhGnss; +pub use msg_protection_level::MsgProtectionLevel; +pub use msg_protection_level_dep_a::MsgProtectionLevelDepA; +pub use msg_utc_time::MsgUtcTime; +pub use msg_utc_time_gnss::MsgUtcTimeGnss; +pub use msg_vel_body::MsgVelBody; +pub use msg_vel_cog::MsgVelCog; +pub use msg_vel_ecef::MsgVelEcef; +pub use msg_vel_ecef_cov::MsgVelEcefCov; +pub use msg_vel_ecef_cov_gnss::MsgVelEcefCovGnss; +pub use msg_vel_ecef_dep_a::MsgVelEcefDepA; +pub use msg_vel_ecef_gnss::MsgVelEcefGnss; +pub use msg_vel_ned::MsgVelNed; +pub use msg_vel_ned_cov::MsgVelNedCov; +pub use msg_vel_ned_cov_gnss::MsgVelNedCovGnss; +pub use msg_vel_ned_dep_a::MsgVelNedDepA; +pub use msg_vel_ned_gnss::MsgVelNedGnss; + +pub mod estimated_horizontal_error_ellipse { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + /// Horizontal estimated error ellipse + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct EstimatedHorizontalErrorEllipse { + /// The semi major axis of the estimated horizontal error ellipse at the + /// user-configured confidence level; zero implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "semi_major")))] + pub semi_major: f32, + /// The semi minor axis of the estimated horizontal error ellipse at the + /// user-configured confidence level; zero implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "semi_minor")))] + pub semi_minor: f32, + /// The orientation of the semi major axis of the estimated horizontal error + /// ellipse with respect to North. + #[cfg_attr(feature = "serde", serde(rename(serialize = "orientation")))] + pub orientation: f32, + } + + impl WireFormat for EstimatedHorizontalErrorEllipse { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.semi_major) + + WireFormat::len(&self.semi_minor) + + WireFormat::len(&self.orientation) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.semi_major, buf); + WireFormat::write(&self.semi_minor, buf); + WireFormat::write(&self.orientation, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + EstimatedHorizontalErrorEllipse { + semi_major: WireFormat::parse_unchecked(buf), + semi_minor: WireFormat::parse_unchecked(buf), + orientation: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for EstimatedHorizontalErrorEllipse { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.semi_major) - + WireFormat::len(&self.semi_minor) - + WireFormat::len(&self.orientation) +pub mod msg_age_corrections { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Age of corrections + /// + /// This message reports the Age of the corrections used for the current + /// Differential solution. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAgeCorrections { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Age of the corrections (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "age")))] + pub age: u16, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.semi_major, buf); - WireFormat::write(&self.semi_minor, buf); - WireFormat::write(&self.orientation, buf); + + impl ConcreteMessage for MsgAgeCorrections { + const MESSAGE_TYPE: u16 = 528; + const MESSAGE_NAME: &'static str = "MSG_AGE_CORRECTIONS"; } - fn parse_unchecked(buf: &mut B) -> Self { - EstimatedHorizontalErrorEllipse { - semi_major: WireFormat::parse_unchecked(buf), - semi_minor: WireFormat::parse_unchecked(buf), - orientation: WireFormat::parse_unchecked(buf), + + impl SbpMessage for MsgAgeCorrections { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -/// Age of corrections -/// -/// This message reports the Age of the corrections used for the current -/// Differential solution. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAgeCorrections { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Age of the corrections (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "age")))] - pub age: u16, -} + impl TryFrom for MsgAgeCorrections { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAgeCorrections(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgAgeCorrections { - const MESSAGE_TYPE: u16 = 528; - const MESSAGE_NAME: &'static str = "MSG_AGE_CORRECTIONS"; + impl WireFormat for MsgAgeCorrections { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + WireFormat::len(&self.age) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.age, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAgeCorrections { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + age: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgAgeCorrections { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_baseline_ecef { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Baseline Position in ECEF + /// + /// This message reports the baseline solution in Earth Centered Earth Fixed + /// (ECEF) coordinates. This baseline is the relative vector distance from the + /// base station to the rover receiver. The full GPS time is given by the + /// preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineEcef { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Baseline ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Baseline ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Baseline ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgBaselineEcef { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgBaselineEcef { + const MESSAGE_TYPE: u16 = 523; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF"; + } + + impl SbpMessage for MsgBaselineEcef { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for MsgBaselineEcef { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineEcef(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl WireFormat for MsgBaselineEcef { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineEcef { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + i => Err(i), + } + } } } -impl TryFrom for MsgAgeCorrections { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAgeCorrections(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_baseline_ecef_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Baseline Position in ECEF + /// + /// This message reports the baseline solution in Earth Centered Earth Fixed + /// (ECEF) coordinates. This baseline is the relative vector distance from the + /// base station to the rover receiver. The full GPS time is given by the + /// preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineEcefDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Baseline ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Baseline ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Baseline ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Position accuracy estimate + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgBaselineEcefDepA { + /// Gets the [RaimRepairFlag][self::RaimRepairFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimRepairFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimRepairFlag` were added. + pub fn raim_repair_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [RaimRepairFlag][RaimRepairFlag] of the `flags` bitfield. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) { + set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4); + } + + /// Gets the [RaimAvailabilityFlag][self::RaimAvailabilityFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimAvailabilityFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimAvailabilityFlag` were added. + pub fn raim_availability_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [RaimAvailabilityFlag][RaimAvailabilityFlag] of the `flags` bitfield. + pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) { + set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); } } -} -impl WireFormat for MsgAgeCorrections { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) + WireFormat::len(&self.age) + impl ConcreteMessage for MsgBaselineEcefDepA { + const MESSAGE_TYPE: u16 = 514; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF_DEP_A"; + } + + impl SbpMessage for MsgBaselineEcefDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.age, buf); + + impl TryFrom for MsgBaselineEcefDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineEcefDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAgeCorrections { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - age: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgBaselineEcefDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineEcefDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// Baseline Position in ECEF -/// -/// This message reports the baseline solution in Earth Centered Earth Fixed -/// (ECEF) coordinates. This baseline is the relative vector distance from the -/// base station to the rover receiver. The full GPS time is given by the -/// preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineEcef { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Baseline ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Baseline ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Baseline ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// RAIM repair flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimRepairFlag { + /// No repair + NoRepair = 0, -impl ConcreteMessage for MsgBaselineEcef { - const MESSAGE_TYPE: u16 = 523; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF"; -} + /// Solution came from RAIM repair + SolutionCameFromRaimRepair = 1, + } -impl SbpMessage for MsgBaselineEcef { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for RaimRepairFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimRepairFlag::NoRepair => f.write_str("No repair"), + RaimRepairFlag::SolutionCameFromRaimRepair => { + f.write_str("Solution came from RAIM repair") + } + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for RaimRepairFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimRepairFlag::NoRepair), + 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// RAIM availability flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimAvailabilityFlag { + /// RAIM check was explicitly disabled or unavailable + RaimCheckWasExplicitlyDisabledOrUnavailable = 0, + + /// RAIM check was available + RaimCheckWasAvailable = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for RaimAvailabilityFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => { + f.write_str("RAIM check was explicitly disabled or unavailable") + } + RaimAvailabilityFlag::RaimCheckWasAvailable => { + f.write_str("RAIM check was available") + } + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for RaimAvailabilityFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable), + 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Float RTK + FloatRtk = 0, + + /// Fixed RTK + FixedRtk = 1, } -} -impl TryFrom for MsgBaselineEcef { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineEcef(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } } } -} -impl WireFormat for MsgBaselineEcef { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineEcef { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::FloatRtk), + 1 => Ok(FixMode::FixedRtk), + i => Err(i), + } } } } -/// Baseline Position in ECEF -/// -/// This message reports the baseline solution in Earth Centered Earth Fixed -/// (ECEF) coordinates. This baseline is the relative vector distance from the -/// base station to the rover receiver. The full GPS time is given by the -/// preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineEcefDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Baseline ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Baseline ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Baseline ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Position accuracy estimate - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_baseline_heading_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Heading relative to True North + /// + /// This message reports the baseline heading pointing from the base station + /// to the rover relative to True North. The full GPS time is given by the + /// preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineHeadingDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Heading + #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] + pub heading: u32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgBaselineHeadingDepA { + /// Gets the [RaimRepairFlag][self::RaimRepairFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimRepairFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimRepairFlag` were added. + pub fn raim_repair_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() + } -impl ConcreteMessage for MsgBaselineEcefDepA { - const MESSAGE_TYPE: u16 = 514; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF_DEP_A"; -} + /// Set the bitrange corresponding to the [RaimRepairFlag][RaimRepairFlag] of the `flags` bitfield. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) { + set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4); + } + + /// Gets the [RaimAvailabilityFlag][self::RaimAvailabilityFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimAvailabilityFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimAvailabilityFlag` were added. + pub fn raim_availability_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } -impl SbpMessage for MsgBaselineEcefDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Set the bitrange corresponding to the [RaimAvailabilityFlag][RaimAvailabilityFlag] of the `flags` bitfield. + pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) { + set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgBaselineHeadingDepA { + const MESSAGE_TYPE: u16 = 519; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_HEADING_DEP_A"; } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl SbpMessage for MsgBaselineHeadingDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MsgBaselineHeadingDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineHeadingDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl WireFormat for MsgBaselineHeadingDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.heading) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.heading, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineHeadingDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + heading: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// RAIM repair flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimRepairFlag { + /// No repair + NoRepair = 0, + + /// Solution came from RAIM repair + SolutionCameFromRaimRepair = 1, } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl std::fmt::Display for RaimRepairFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimRepairFlag::NoRepair => f.write_str("No repair"), + RaimRepairFlag::SolutionCameFromRaimRepair => { + f.write_str("Solution came from RAIM repair") + } + } + } } -} -impl TryFrom for MsgBaselineEcefDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineEcefDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for RaimRepairFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimRepairFlag::NoRepair), + 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair), + i => Err(i), + } } } -} -impl WireFormat for MsgBaselineEcefDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineEcefDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + /// RAIM availability flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimAvailabilityFlag { + /// RAIM check was explicitly disabled or unavailable + RaimCheckWasExplicitlyDisabledOrUnavailable = 0, + + /// RAIM check was available + RaimCheckWasAvailable = 1, + } + + impl std::fmt::Display for RaimAvailabilityFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => { + f.write_str("RAIM check was explicitly disabled or unavailable") + } + RaimAvailabilityFlag::RaimCheckWasAvailable => { + f.write_str("RAIM check was available") + } + } } } -} -/// Heading relative to True North -/// -/// This message reports the baseline heading pointing from the base station -/// to the rover relative to True North. The full GPS time is given by the -/// preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineHeadingDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Heading - #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] - pub heading: u32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl TryFrom for RaimAvailabilityFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable), + 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Float RTK + FloatRtk = 0, + + /// Fixed RTK + FixedRtk = 1, + } -impl ConcreteMessage for MsgBaselineHeadingDepA { - const MESSAGE_TYPE: u16 = 519; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_HEADING_DEP_A"; + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::FloatRtk), + 1 => Ok(FixMode::FixedRtk), + i => Err(i), + } + } + } } -impl SbpMessage for MsgBaselineHeadingDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_baseline_ned { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Baseline in NED + /// + /// This message reports the baseline solution in North East Down (NED) + /// coordinates. This baseline is the relative vector distance from the base + /// station to the rover receiver, and NED coordinate system is defined at the + /// local WGS84 tangent plane centered at the base station position. The full + /// GPS time is given by the preceding MSG_GPS_TIME with the matching time-of- + /// week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineNed { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Baseline North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Baseline East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Baseline Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Horizontal position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgBaselineNed { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgBaselineNed { + const MESSAGE_TYPE: u16 = 524; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgBaselineNed { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgBaselineNed { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineNed(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgBaselineNed { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineNed { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, } -} -impl TryFrom for MsgBaselineHeadingDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineHeadingDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } } } -} -impl WireFormat for MsgBaselineHeadingDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.heading) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.heading, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineHeadingDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - heading: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + i => Err(i), + } } } } -/// Baseline in NED -/// -/// This message reports the baseline solution in North East Down (NED) -/// coordinates. This baseline is the relative vector distance from the base -/// station to the rover receiver, and NED coordinate system is defined at the -/// local WGS84 tangent plane centered at the base station position. The full -/// GPS time is given by the preceding MSG_GPS_TIME with the matching time-of- -/// week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineNed { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Baseline North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Baseline East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Baseline Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Horizontal position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_baseline_ned_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Baseline in NED + /// + /// This message reports the baseline solution in North East Down (NED) + /// coordinates. This baseline is the relative vector distance from the base + /// station to the rover receiver, and NED coordinate system is defined at the + /// local WGS84 tangent plane centered at the base station position. The full + /// GPS time is given by the preceding MSG_GPS_TIME with the matching time-of- + /// week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineNedDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Baseline North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Baseline East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Baseline Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Horizontal position accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical position accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgBaselineNedDepA { + /// Gets the [RaimRepairFlag][self::RaimRepairFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimRepairFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimRepairFlag` were added. + pub fn raim_repair_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() + } -impl ConcreteMessage for MsgBaselineNed { - const MESSAGE_TYPE: u16 = 524; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED"; -} + /// Set the bitrange corresponding to the [RaimRepairFlag][RaimRepairFlag] of the `flags` bitfield. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) { + set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4); + } + + /// Gets the [RaimAvailabilityFlag][self::RaimAvailabilityFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimAvailabilityFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimAvailabilityFlag` were added. + pub fn raim_availability_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [RaimAvailabilityFlag][RaimAvailabilityFlag] of the `flags` bitfield. + pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) { + set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3); + } -impl SbpMessage for MsgBaselineNed { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgBaselineNedDepA { + const MESSAGE_TYPE: u16 = 515; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED_DEP_A"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgBaselineNedDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgBaselineNedDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineNedDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgBaselineNedDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineNedDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// RAIM repair flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimRepairFlag { + /// No repair + NoRepair = 0, + + /// Solution came from RAIM repair + SolutionCameFromRaimRepair = 1, } -} -impl TryFrom for MsgBaselineNed { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineNed(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for RaimRepairFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimRepairFlag::NoRepair => f.write_str("No repair"), + RaimRepairFlag::SolutionCameFromRaimRepair => { + f.write_str("Solution came from RAIM repair") + } + } } } -} -impl WireFormat for MsgBaselineNed { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineNed { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for RaimRepairFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimRepairFlag::NoRepair), + 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair), + i => Err(i), + } } } -} -/// Baseline in NED -/// -/// This message reports the baseline solution in North East Down (NED) -/// coordinates. This baseline is the relative vector distance from the base -/// station to the rover receiver, and NED coordinate system is defined at the -/// local WGS84 tangent plane centered at the base station position. The full -/// GPS time is given by the preceding MSG_GPS_TIME with the matching time-of- -/// week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineNedDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Baseline North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Baseline East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Baseline Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Horizontal position accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical position accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// RAIM availability flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimAvailabilityFlag { + /// RAIM check was explicitly disabled or unavailable + RaimCheckWasExplicitlyDisabledOrUnavailable = 0, + + /// RAIM check was available + RaimCheckWasAvailable = 1, + } + + impl std::fmt::Display for RaimAvailabilityFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => { + f.write_str("RAIM check was explicitly disabled or unavailable") + } + RaimAvailabilityFlag::RaimCheckWasAvailable => { + f.write_str("RAIM check was available") + } + } + } + } + + impl TryFrom for RaimAvailabilityFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable), + 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Float RTK + FloatRtk = 0, -impl ConcreteMessage for MsgBaselineNedDepA { - const MESSAGE_TYPE: u16 = 515; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED_DEP_A"; + /// Fixed RTK + FixedRtk = 1, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::FloatRtk), + 1 => Ok(FixMode::FixedRtk), + i => Err(i), + } + } + } } -impl SbpMessage for MsgBaselineNedDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_dops { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Dilution of Precision + /// + /// This dilution of precision (DOP) message describes the effect of + /// navigation satellite geometry on positional measurement precision. The + /// flags field indicated whether the DOP reported corresponds to differential + /// or SPP solution. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgDops { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Geometric Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "gdop")))] + pub gdop: u16, + /// Position Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] + pub pdop: u16, + /// Time Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "tdop")))] + pub tdop: u16, + /// Horizontal Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] + pub hdop: u16, + /// Vertical Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] + pub vdop: u16, + /// Indicates the position solution with which the DOPS message corresponds + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgDops { + /// Gets the `raim_repair_flag` flag. + pub fn raim_repair_flag(&self) -> bool { + ((self.flags >> 7) & 1) == 1 + } + + /// Sets the `raim_repair_flag` flag. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: bool) { + self.flags ^= (!(raim_repair_flag as u8)) & (1 << 7) + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgDops { + const MESSAGE_TYPE: u16 = 520; + const MESSAGE_NAME: &'static str = "MSG_DOPS"; + } + + impl SbpMessage for MsgDops { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for MsgDops { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgDops(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl WireFormat for MsgDops { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.gdop) + + WireFormat::len(&self.pdop) + + WireFormat::len(&self.tdop) + + WireFormat::len(&self.hdop) + + WireFormat::len(&self.vdop) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.gdop, buf); + WireFormat::write(&self.pdop, buf); + WireFormat::write(&self.tdop, buf); + WireFormat::write(&self.hdop, buf); + WireFormat::write(&self.vdop, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgDops { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + gdop: WireFormat::parse_unchecked(buf), + pdop: WireFormat::parse_unchecked(buf), + tdop: WireFormat::parse_unchecked(buf), + hdop: WireFormat::parse_unchecked(buf), + vdop: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Undefined + Undefined = 5, + + /// SBAS Position + SbasPosition = 6, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::Undefined => f.write_str("Undefined"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::Undefined), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } } } -impl TryFrom for MsgBaselineNedDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineNedDepA(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_dops_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Dilution of Precision + /// + /// This dilution of precision (DOP) message describes the effect of + /// navigation satellite geometry on positional measurement precision. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgDopsDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Geometric Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "gdop")))] + pub gdop: u16, + /// Position Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] + pub pdop: u16, + /// Time Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "tdop")))] + pub tdop: u16, + /// Horizontal Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] + pub hdop: u16, + /// Vertical Dilution of Precision + #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] + pub vdop: u16, + } + + impl ConcreteMessage for MsgDopsDepA { + const MESSAGE_TYPE: u16 = 518; + const MESSAGE_NAME: &'static str = "MSG_DOPS_DEP_A"; + } + + impl SbpMessage for MsgDopsDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgDopsDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgDopsDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgDopsDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.gdop) + + WireFormat::len(&self.pdop) + + WireFormat::len(&self.tdop) + + WireFormat::len(&self.hdop) + + WireFormat::len(&self.vdop) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.gdop, buf); + WireFormat::write(&self.pdop, buf); + WireFormat::write(&self.tdop, buf); + WireFormat::write(&self.hdop, buf); + WireFormat::write(&self.vdop, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgDopsDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + gdop: WireFormat::parse_unchecked(buf), + pdop: WireFormat::parse_unchecked(buf), + tdop: WireFormat::parse_unchecked(buf), + hdop: WireFormat::parse_unchecked(buf), + vdop: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_gps_time { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GPS Time + /// + /// This message reports the GPS time, representing the time since the GPS + /// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and + /// seconds of the week. The weeks begin at the Saturday/Sunday transition. + /// GPS week 0 began at the beginning of the GPS time scale. + /// + /// Within each week number, the GPS time of the week is between between 0 and + /// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap + /// seconds, and as of now, has a small offset from UTC. In a message stream, + /// this message precedes a set of other navigation messages referenced to the + /// same time (but lacking the ns field) and indicates a more precise time of + /// these messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGpsTime { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to + /// 500000) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] + pub ns_residual: i32, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgGpsTime { + /// Gets the [TimeSource][self::TimeSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeSource` were added. + pub fn time_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeSource][TimeSource] of the `flags` bitfield. + pub fn set_time_source(&mut self, time_source: TimeSource) { + set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgGpsTime { + const MESSAGE_TYPE: u16 = 258; + const MESSAGE_NAME: &'static str = "MSG_GPS_TIME"; + } + + impl SbpMessage for MsgGpsTime { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + #[allow(clippy::useless_conversion)] + let wn: i16 = match self.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgGpsTime { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGpsTime(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgGpsTime { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.wn) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.ns_residual) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.wn, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.ns_residual, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGpsTime { + sender_id: None, + wn: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + ns_residual: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Time source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeSource { + /// None (invalid) + None = 0, + + /// GNSS Solution + GnssSolution = 1, + + /// Propagated + Propagated = 2, + } + + impl std::fmt::Display for TimeSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeSource::None => f.write_str("None (invalid)"), + TimeSource::GnssSolution => f.write_str("GNSS Solution"), + TimeSource::Propagated => f.write_str("Propagated"), + } + } + } + + impl TryFrom for TimeSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeSource::None), + 1 => Ok(TimeSource::GnssSolution), + 2 => Ok(TimeSource::Propagated), + i => Err(i), + } + } + } +} + +pub mod msg_gps_time_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GPS Time (v1.0) + /// + /// This message reports the GPS time, representing the time since the GPS + /// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and + /// seconds of the week. The weeks begin at the Saturday/Sunday transition. + /// GPS week 0 began at the beginning of the GPS time scale. + /// + /// Within each week number, the GPS time of the week is between between 0 and + /// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap + /// seconds, and as of now, has a small offset from UTC. In a message stream, + /// this message precedes a set of other navigation messages referenced to the + /// same time (but lacking the ns field) and indicates a more precise time of + /// these messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGpsTimeDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to + /// 500000) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] + pub ns_residual: i32, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl ConcreteMessage for MsgGpsTimeDepA { + const MESSAGE_TYPE: u16 = 256; + const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_DEP_A"; + } + + impl SbpMessage for MsgGpsTimeDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + #[allow(clippy::useless_conversion)] + let wn: i16 = match self.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgGpsTimeDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGpsTimeDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgGpsTimeDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.wn) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.ns_residual) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.wn, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.ns_residual, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGpsTimeDepA { + sender_id: None, + wn: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + ns_residual: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_gps_time_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GPS Time + /// + /// This message reports the GPS time, representing the time since the GPS + /// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and + /// seconds of the week. The weeks begin at the Saturday/Sunday transition. + /// GPS week 0 began at the beginning of the GPS time scale. + /// + /// Within each week number, the GPS time of the week is between between 0 and + /// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap + /// seconds, and as of now, has a small offset from UTC. In a message stream, + /// this message precedes a set of other navigation messages referenced to the + /// same time (but lacking the ns field) and indicates a more precise time of + /// these messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGpsTimeGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: u16, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to + /// 500000) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] + pub ns_residual: i32, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgGpsTimeGnss { + /// Gets the [TimeSource][self::TimeSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeSource` were added. + pub fn time_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeSource][TimeSource] of the `flags` bitfield. + pub fn set_time_source(&mut self, time_source: TimeSource) { + set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgGpsTimeGnss { + const MESSAGE_TYPE: u16 = 260; + const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_GNSS"; + } + + impl SbpMessage for MsgGpsTimeGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + #[allow(clippy::useless_conversion)] + let wn: i16 = match self.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgGpsTimeGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGpsTimeGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgGpsTimeGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.wn) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.ns_residual) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.wn, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.ns_residual, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGpsTimeGnss { + sender_id: None, + wn: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + ns_residual: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Time source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeSource { + /// None (invalid) + None = 0, + + /// GNSS Solution + GnssSolution = 1, + + /// Propagated + Propagated = 2, + } + + impl std::fmt::Display for TimeSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeSource::None => f.write_str("None (invalid)"), + TimeSource::GnssSolution => f.write_str("GNSS Solution"), + TimeSource::Propagated => f.write_str("Propagated"), + } + } + } + + impl TryFrom for TimeSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeSource::None), + 1 => Ok(TimeSource::GnssSolution), + 2 => Ok(TimeSource::Propagated), + i => Err(i), + } + } + } +} + +pub mod msg_pos_ecef { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Single-point position in ECEF + /// + /// The position solution message reports absolute Earth Centered Earth Fixed + /// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of + /// the position solution. If the rover receiver knows the surveyed position + /// of the base station and has an RTK solution, this reports a pseudo- + /// absolute position solution using the base station position and the rover's + /// RTK baseline vector. The full GPS time is given by the preceding + /// MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosEcef { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + /// Position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosEcef { + /// Gets the [TowType][self::TowType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TowType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TowType` were added. + pub fn tow_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [TowType][TowType] of the `flags` bitfield. + pub fn set_tow_type(&mut self, tow_type: TowType) { + set_bit_range!(&mut self.flags, tow_type, u8, u8, 5, 5); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosEcef { + const MESSAGE_TYPE: u16 = 521; + const MESSAGE_NAME: &'static str = "MSG_POS_ECEF"; + } + + impl SbpMessage for MsgPosEcef { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosEcef { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosEcef(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosEcef { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosEcef { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// TOW type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TowType { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TowType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TowType::TimeOfMeasurement => f.write_str("Time of Measurement"), + TowType::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TowType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TowType::TimeOfMeasurement), + 1 => Ok(TowType::Other), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_ecef_cov { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Single-point position in ECEF + /// + /// The position solution message reports absolute Earth Centered Earth Fixed + /// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of + /// the position solution. The message also reports the upper triangular + /// portion of the 3x3 covariance matrix. If the receiver knows the surveyed + /// position of the base station and has an RTK solution, this reports a + /// pseudo-absolute position solution using the base station position and the + /// rover's RTK baseline vector. The full GPS time is given by the preceding + /// MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosEcefCov { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + /// Estimated variance of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] + pub cov_x_x: f32, + /// Estimated covariance of x and y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] + pub cov_x_y: f32, + /// Estimated covariance of x and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] + pub cov_x_z: f32, + /// Estimated variance of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] + pub cov_y_y: f32, + /// Estimated covariance of y and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] + pub cov_y_z: f32, + /// Estimated variance of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] + pub cov_z_z: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosEcefCov { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosEcefCov { + const MESSAGE_TYPE: u16 = 532; + const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV"; + } + + impl SbpMessage for MsgPosEcefCov { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosEcefCov { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosEcefCov(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosEcefCov { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.cov_x_x) + + WireFormat::len(&self.cov_x_y) + + WireFormat::len(&self.cov_x_z) + + WireFormat::len(&self.cov_y_y) + + WireFormat::len(&self.cov_y_z) + + WireFormat::len(&self.cov_z_z) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.cov_x_x, buf); + WireFormat::write(&self.cov_x_y, buf); + WireFormat::write(&self.cov_x_z, buf); + WireFormat::write(&self.cov_y_y, buf); + WireFormat::write(&self.cov_y_z, buf); + WireFormat::write(&self.cov_z_z, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosEcefCov { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + cov_x_x: WireFormat::parse_unchecked(buf), + cov_x_y: WireFormat::parse_unchecked(buf), + cov_x_z: WireFormat::parse_unchecked(buf), + cov_y_y: WireFormat::parse_unchecked(buf), + cov_y_z: WireFormat::parse_unchecked(buf), + cov_z_z: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_ecef_cov_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Position in ECEF + /// + /// The position solution message reports absolute Earth Centered Earth Fixed + /// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of + /// the position solution. The message also reports the upper triangular + /// portion of the 3x3 covariance matrix. If the receiver knows the surveyed + /// position of the base station and has an RTK solution, this reports a + /// pseudo-absolute position solution using the base station position and the + /// rover's RTK baseline vector. The full GPS time is given by the preceding + /// MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosEcefCovGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + /// Estimated variance of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] + pub cov_x_x: f32, + /// Estimated covariance of x and y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] + pub cov_x_y: f32, + /// Estimated covariance of x and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] + pub cov_x_z: f32, + /// Estimated variance of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] + pub cov_y_y: f32, + /// Estimated covariance of y and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] + pub cov_y_z: f32, + /// Estimated variance of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] + pub cov_z_z: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosEcefCovGnss { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosEcefCovGnss { + const MESSAGE_TYPE: u16 = 564; + const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV_GNSS"; + } + + impl SbpMessage for MsgPosEcefCovGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosEcefCovGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosEcefCovGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosEcefCovGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.cov_x_x) + + WireFormat::len(&self.cov_x_y) + + WireFormat::len(&self.cov_x_z) + + WireFormat::len(&self.cov_y_y) + + WireFormat::len(&self.cov_y_z) + + WireFormat::len(&self.cov_z_z) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.cov_x_x, buf); + WireFormat::write(&self.cov_x_y, buf); + WireFormat::write(&self.cov_x_z, buf); + WireFormat::write(&self.cov_y_y, buf); + WireFormat::write(&self.cov_y_z, buf); + WireFormat::write(&self.cov_z_z, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosEcefCovGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + cov_x_x: WireFormat::parse_unchecked(buf), + cov_x_y: WireFormat::parse_unchecked(buf), + cov_x_z: WireFormat::parse_unchecked(buf), + cov_y_y: WireFormat::parse_unchecked(buf), + cov_y_z: WireFormat::parse_unchecked(buf), + cov_z_z: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_ecef_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Single-point position in ECEF + /// + /// The position solution message reports absolute Earth Centered Earth Fixed + /// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of + /// the position solution. If the rover receiver knows the surveyed position + /// of the base station and has an RTK solution, this reports a pseudo- + /// absolute position solution using the base station position and the rover's + /// RTK baseline vector. The full GPS time is given by the preceding + /// MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosEcefDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + /// Position accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosEcefDepA { + /// Gets the [RaimRepairFlag][self::RaimRepairFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimRepairFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimRepairFlag` were added. + pub fn raim_repair_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [RaimRepairFlag][RaimRepairFlag] of the `flags` bitfield. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) { + set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4); + } + + /// Gets the [RaimAvailabilityFlag][self::RaimAvailabilityFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimAvailabilityFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimAvailabilityFlag` were added. + pub fn raim_availability_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [RaimAvailabilityFlag][RaimAvailabilityFlag] of the `flags` bitfield. + pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) { + set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosEcefDepA { + const MESSAGE_TYPE: u16 = 512; + const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_DEP_A"; + } + + impl SbpMessage for MsgPosEcefDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosEcefDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosEcefDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosEcefDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosEcefDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// RAIM repair flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimRepairFlag { + /// No repair + NoRepair = 0, + + /// Solution came from RAIM repair + SolutionCameFromRaimRepair = 1, + } + + impl std::fmt::Display for RaimRepairFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimRepairFlag::NoRepair => f.write_str("No repair"), + RaimRepairFlag::SolutionCameFromRaimRepair => { + f.write_str("Solution came from RAIM repair") + } + } + } + } + + impl TryFrom for RaimRepairFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimRepairFlag::NoRepair), + 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair), + i => Err(i), + } + } + } + + /// RAIM availability flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimAvailabilityFlag { + /// RAIM check was explicitly disabled or unavailable + RaimCheckWasExplicitlyDisabledOrUnavailable = 0, + + /// RAIM check was available + RaimCheckWasAvailable = 1, + } + + impl std::fmt::Display for RaimAvailabilityFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => { + f.write_str("RAIM check was explicitly disabled or unavailable") + } + RaimAvailabilityFlag::RaimCheckWasAvailable => { + f.write_str("RAIM check was available") + } + } + } + } + + impl TryFrom for RaimAvailabilityFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable), + 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Single Point Positioning (SPP) + SinglePointPositioning = 0, + + /// Fixed RTK + FixedRtk = 1, + + /// Float RTK + FloatRtk = 2, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::SinglePointPositioning => f.write_str("Single Point Positioning (SPP)"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::FloatRtk => f.write_str("Float RTK"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::SinglePointPositioning), + 1 => Ok(FixMode::FixedRtk), + 2 => Ok(FixMode::FloatRtk), + i => Err(i), + } + } + } +} + +pub mod msg_pos_ecef_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Position in ECEF + /// + /// The position solution message reports absolute Earth Centered Earth Fixed + /// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of + /// the position solution. If the rover receiver knows the surveyed position + /// of the base station and has an RTK solution, this reports a pseudo- + /// absolute position solution using the base station position and the rover's + /// RTK baseline vector. The full GPS time is given by the preceding + /// MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosEcefGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + /// Position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosEcefGnss { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosEcefGnss { + const MESSAGE_TYPE: u16 = 553; + const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_GNSS"; + } + + impl SbpMessage for MsgPosEcefGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosEcefGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosEcefGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosEcefGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosEcefGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Geodetic Position + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution. If the rover receiver knows the surveyed position of the base + /// station and has an RTK solution, this reports a pseudo-absolute position + /// solution using the base station position and the rover's RTK baseline + /// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the + /// matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlh { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height above WGS84 ellipsoid + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Horizontal position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlh { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlh { + const MESSAGE_TYPE: u16 = 522; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH"; + } + + impl SbpMessage for MsgPosLlh { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlh { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlh(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlh { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlh { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh_acc { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Geodetic Position and Accuracy + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution as well as the estimated horizontal, vertical, cross-track and + /// along-track errors. The position information and Fix Mode flags follow + /// the MSG_POS_LLH message. Since the covariance matrix is computed in the + /// local-level North, East, Down frame, the estimated error terms follow that + /// convention. + /// + /// The estimated errors are reported at a user-configurable confidence level. + /// The user-configured percentile is encoded in the percentile field. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlhAcc { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height above WGS84 ellipsoid + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Height above the geoid (i.e. height above mean sea level). See + /// confidence_and_geoid for geoid model used. + #[cfg_attr(feature = "serde", serde(rename(serialize = "orthometric_height")))] + pub orthometric_height: f64, + /// Estimated horizontal error at the user-configured confidence level; zero + /// implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: f32, + /// Estimated vertical error at the user-configured confidence level; zero + /// implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: f32, + /// Estimated cross-track error at the user-configured confidence level; + /// zero implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "ct_accuracy")))] + pub ct_accuracy: f32, + /// Estimated along-track error at the user-configured confidence level; + /// zero implies invalid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "at_accuracy")))] + pub at_accuracy: f32, + /// The estimated horizontal error ellipse at the user-configured confidence + /// level. + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_ellipse")))] + pub h_ellipse: EstimatedHorizontalErrorEllipse, + /// The lower bits describe the configured confidence level for the + /// estimated position error. The middle bits describe the geoid model used + /// to calculate the orthometric height. + #[cfg_attr(feature = "serde", serde(rename(serialize = "confidence_and_geoid")))] + pub confidence_and_geoid: u8, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlhAcc { + /// Gets the [GeoidModel][self::GeoidModel] stored in the `confidence_and_geoid` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `GeoidModel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `GeoidModel` were added. + pub fn geoid_model(&self) -> Result { + get_bit_range!(self.confidence_and_geoid, u8, u8, 6, 4).try_into() + } + + /// Set the bitrange corresponding to the [GeoidModel][GeoidModel] of the `confidence_and_geoid` bitfield. + pub fn set_geoid_model(&mut self, geoid_model: GeoidModel) { + set_bit_range!(&mut self.confidence_and_geoid, geoid_model, u8, u8, 6, 4); + } + + /// Gets the [ConfidenceLevel][self::ConfidenceLevel] stored in the `confidence_and_geoid` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ConfidenceLevel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ConfidenceLevel` were added. + pub fn confidence_level(&self) -> Result { + get_bit_range!(self.confidence_and_geoid, u8, u8, 3, 0).try_into() + } + + /// Set the bitrange corresponding to the [ConfidenceLevel][ConfidenceLevel] of the `confidence_and_geoid` bitfield. + pub fn set_confidence_level(&mut self, confidence_level: ConfidenceLevel) { + set_bit_range!( + &mut self.confidence_and_geoid, + confidence_level, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlhAcc { + const MESSAGE_TYPE: u16 = 536; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH_ACC"; + } + + impl SbpMessage for MsgPosLlhAcc { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlhAcc { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlhAcc(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlhAcc { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.orthometric_height) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.ct_accuracy) + + WireFormat::len(&self.at_accuracy) + + WireFormat::len(&self.h_ellipse) + + WireFormat::len(&self.confidence_and_geoid) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.orthometric_height, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.ct_accuracy, buf); + WireFormat::write(&self.at_accuracy, buf); + WireFormat::write(&self.h_ellipse, buf); + WireFormat::write(&self.confidence_and_geoid, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlhAcc { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + orthometric_height: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + ct_accuracy: WireFormat::parse_unchecked(buf), + at_accuracy: WireFormat::parse_unchecked(buf), + h_ellipse: WireFormat::parse_unchecked(buf), + confidence_and_geoid: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Geoid model + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum GeoidModel { + /// No model + NoModel = 0, + + /// EGM96 + EGM96 = 1, + + /// EGM2008 + EGM2008 = 2, + } + + impl std::fmt::Display for GeoidModel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GeoidModel::NoModel => f.write_str("No model"), + GeoidModel::EGM96 => f.write_str("EGM96"), + GeoidModel::EGM2008 => f.write_str("EGM2008"), + } + } + } + + impl TryFrom for GeoidModel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(GeoidModel::NoModel), + 1 => Ok(GeoidModel::EGM96), + 2 => Ok(GeoidModel::EGM2008), + i => Err(i), + } + } + } + + /// Confidence level + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ConfidenceLevel { + /// 39.35% + _3935 = 1, + + /// 68.27% + _6827 = 2, + + /// 95.45% + _9545 = 3, + } + + impl std::fmt::Display for ConfidenceLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ConfidenceLevel::_3935 => f.write_str("39.35%"), + ConfidenceLevel::_6827 => f.write_str("68.27%"), + ConfidenceLevel::_9545 => f.write_str("95.45%"), + } + } + } + + impl TryFrom for ConfidenceLevel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 1 => Ok(ConfidenceLevel::_3935), + 2 => Ok(ConfidenceLevel::_6827), + 3 => Ok(ConfidenceLevel::_9545), + i => Err(i), + } + } + } + + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh_cov { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Geodetic Position + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution as well as the upper triangle of the 3x3 covariance matrix. The + /// position information and Fix Mode flags follow the MSG_POS_LLH message. + /// Since the covariance matrix is computed in the local-level North, East, + /// Down frame, the covariance terms follow that convention. Thus, covariances + /// are reported against the "downward" measurement and care should be taken + /// with the sign convention. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlhCov { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height above WGS84 ellipsoid + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Estimated variance of northing + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] + pub cov_n_n: f32, + /// Covariance of northing and easting + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] + pub cov_n_e: f32, + /// Covariance of northing and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] + pub cov_n_d: f32, + /// Estimated variance of easting + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] + pub cov_e_e: f32, + /// Covariance of easting and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] + pub cov_e_d: f32, + /// Estimated variance of downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] + pub cov_d_d: f32, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlhCov { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlhCov { + const MESSAGE_TYPE: u16 = 529; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV"; + } + + impl SbpMessage for MsgPosLlhCov { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlhCov { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlhCov(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlhCov { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.cov_n_n) + + WireFormat::len(&self.cov_n_e) + + WireFormat::len(&self.cov_n_d) + + WireFormat::len(&self.cov_e_e) + + WireFormat::len(&self.cov_e_d) + + WireFormat::len(&self.cov_d_d) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.cov_n_n, buf); + WireFormat::write(&self.cov_n_e, buf); + WireFormat::write(&self.cov_n_d, buf); + WireFormat::write(&self.cov_e_e, buf); + WireFormat::write(&self.cov_e_d, buf); + WireFormat::write(&self.cov_d_d, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlhCov { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + cov_n_n: WireFormat::parse_unchecked(buf), + cov_n_e: WireFormat::parse_unchecked(buf), + cov_n_d: WireFormat::parse_unchecked(buf), + cov_e_e: WireFormat::parse_unchecked(buf), + cov_e_d: WireFormat::parse_unchecked(buf), + cov_d_d: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh_cov_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Geodetic Position + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution as well as the upper triangle of the 3x3 covariance matrix. The + /// position information and Fix Mode flags should follow the MSG_POS_LLH + /// message. Since the covariance matrix is computed in the local-level + /// North, East, Down frame, the covariance terms follow with that convention. + /// Thus, covariances are reported against the "downward" measurement and care + /// should be taken with the sign convention. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlhCovGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height above WGS84 ellipsoid + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Estimated variance of northing + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] + pub cov_n_n: f32, + /// Covariance of northing and easting + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] + pub cov_n_e: f32, + /// Covariance of northing and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] + pub cov_n_d: f32, + /// Estimated variance of easting + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] + pub cov_e_e: f32, + /// Covariance of easting and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] + pub cov_e_d: f32, + /// Estimated variance of downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] + pub cov_d_d: f32, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlhCovGnss { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlhCovGnss { + const MESSAGE_TYPE: u16 = 561; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV_GNSS"; + } + + impl SbpMessage for MsgPosLlhCovGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlhCovGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlhCovGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlhCovGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.cov_n_n) + + WireFormat::len(&self.cov_n_e) + + WireFormat::len(&self.cov_n_d) + + WireFormat::len(&self.cov_e_e) + + WireFormat::len(&self.cov_e_d) + + WireFormat::len(&self.cov_d_d) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.cov_n_n, buf); + WireFormat::write(&self.cov_n_e, buf); + WireFormat::write(&self.cov_n_d, buf); + WireFormat::write(&self.cov_e_e, buf); + WireFormat::write(&self.cov_e_d, buf); + WireFormat::write(&self.cov_d_d, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlhCovGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + cov_n_n: WireFormat::parse_unchecked(buf), + cov_n_e: WireFormat::parse_unchecked(buf), + cov_n_d: WireFormat::parse_unchecked(buf), + cov_e_e: WireFormat::parse_unchecked(buf), + cov_e_d: WireFormat::parse_unchecked(buf), + cov_d_d: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Geodetic Position + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution. If the rover receiver knows the surveyed position of the base + /// station and has an RTK solution, this reports a pseudo-absolute position + /// solution using the base station position and the rover's RTK baseline + /// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the + /// matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlhDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Horizontal position accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical position accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlhDepA { + /// Gets the [RaimRepairFlag][self::RaimRepairFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimRepairFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimRepairFlag` were added. + pub fn raim_repair_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [RaimRepairFlag][RaimRepairFlag] of the `flags` bitfield. + pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) { + set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 5, 5); + } + + /// Gets the [RaimAvailabilityFlag][self::RaimAvailabilityFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimAvailabilityFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimAvailabilityFlag` were added. + pub fn raim_availability_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [RaimAvailabilityFlag][RaimAvailabilityFlag] of the `flags` bitfield. + pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) { + set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 4, 4); + } + + /// Gets the [HeightMode][self::HeightMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `HeightMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `HeightMode` were added. + pub fn height_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [HeightMode][HeightMode] of the `flags` bitfield. + pub fn set_height_mode(&mut self, height_mode: HeightMode) { + set_bit_range!(&mut self.flags, height_mode, u8, u8, 3, 3); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlhDepA { + const MESSAGE_TYPE: u16 = 513; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH_DEP_A"; + } + + impl SbpMessage for MsgPosLlhDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlhDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlhDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlhDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlhDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// RAIM repair flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimRepairFlag { + /// No repair + NoRepair = 0, + + /// Solution came from RAIM repair + SolutionCameFromRaimRepair = 1, + } + + impl std::fmt::Display for RaimRepairFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimRepairFlag::NoRepair => f.write_str("No repair"), + RaimRepairFlag::SolutionCameFromRaimRepair => { + f.write_str("Solution came from RAIM repair") + } + } + } + } + + impl TryFrom for RaimRepairFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimRepairFlag::NoRepair), + 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair), + i => Err(i), + } + } + } + + /// RAIM availability flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimAvailabilityFlag { + /// RAIM check was explicitly disabled or unavailable + RaimCheckWasExplicitlyDisabledOrUnavailable = 0, + + /// RAIM check was available + RaimCheckWasAvailable = 1, + } + + impl std::fmt::Display for RaimAvailabilityFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => { + f.write_str("RAIM check was explicitly disabled or unavailable") + } + RaimAvailabilityFlag::RaimCheckWasAvailable => { + f.write_str("RAIM check was available") + } + } + } + } + + impl TryFrom for RaimAvailabilityFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable), + 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable), + i => Err(i), + } + } + } + + /// Height Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum HeightMode { + /// Height above WGS84 ellipsoid + HeightAboveWgs84Ellipsoid = 0, + + /// Height above mean sea level + HeightAboveMeanSeaLevel = 1, + } + + impl std::fmt::Display for HeightMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + HeightMode::HeightAboveWgs84Ellipsoid => { + f.write_str("Height above WGS84 ellipsoid") + } + HeightMode::HeightAboveMeanSeaLevel => f.write_str("Height above mean sea level"), + } + } + } + + impl TryFrom for HeightMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(HeightMode::HeightAboveWgs84Ellipsoid), + 1 => Ok(HeightMode::HeightAboveMeanSeaLevel), + i => Err(i), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Single Point Positioning (SPP) + SinglePointPositioning = 0, + + /// Fixed RTK + FixedRtk = 1, + + /// Float RTK + FloatRtk = 2, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::SinglePointPositioning => f.write_str("Single Point Positioning (SPP)"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::FloatRtk => f.write_str("Float RTK"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::SinglePointPositioning), + 1 => Ok(FixMode::FixedRtk), + 2 => Ok(FixMode::FloatRtk), + i => Err(i), + } + } + } +} + +pub mod msg_pos_llh_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Geodetic Position + /// + /// This position solution message reports the absolute geodetic coordinates + /// and the status (single point vs pseudo-absolute RTK) of the position + /// solution. If the rover receiver knows the surveyed position of the base + /// station and has an RTK solution, this reports a pseudo-absolute position + /// solution using the base station position and the rover's RTK baseline + /// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the + /// matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPosLlhGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height above WGS84 ellipsoid + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Horizontal position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical position estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPosLlhGnss { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgPosLlhGnss { + const MESSAGE_TYPE: u16 = 554; + const MESSAGE_NAME: &'static str = "MSG_POS_LLH_GNSS"; + } + + impl SbpMessage for MsgPosLlhGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgPosLlhGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPosLlhGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgPosLlhGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPosLlhGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } +} + +pub mod msg_protection_level { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Computed state and Protection Levels + /// + /// This message reports the protection levels associated to the given state + /// estimate. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgProtectionLevel { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// GPS week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] + pub wn: i16, + /// Horizontal protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "hpl")))] + pub hpl: u16, + /// Vertical protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "vpl")))] + pub vpl: u16, + /// Along-track position error protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "atpl")))] + pub atpl: u16, + /// Cross-track position error protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "ctpl")))] + pub ctpl: u16, + /// Protection level for the error vector between estimated and true + /// along/cross track velocity vector + #[cfg_attr(feature = "serde", serde(rename(serialize = "hvpl")))] + pub hvpl: u16, + /// Protection level for the velocity in vehicle upright direction + /// (different from vertical direction if on a slope) + #[cfg_attr(feature = "serde", serde(rename(serialize = "vvpl")))] + pub vvpl: u16, + /// Heading orientation protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "hopl")))] + pub hopl: u16, + /// Pitch orientation protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "popl")))] + pub popl: u16, + /// Roll orientation protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "ropl")))] + pub ropl: u16, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Velocity in vehicle x direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_x")))] + pub v_x: i32, + /// Velocity in vehicle y direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_y")))] + pub v_y: i32, + /// Velocity in vehicle z direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_z")))] + pub v_z: i32, + /// Roll angle + #[cfg_attr(feature = "serde", serde(rename(serialize = "roll")))] + pub roll: i32, + /// Pitch angle + #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch")))] + pub pitch: i32, + /// Heading angle + #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] + pub heading: i32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgProtectionLevel { + /// Gets the `target_integrity_risk_tir_level` stored in `flags`. + pub fn target_integrity_risk_tir_level(&self) -> u8 { + get_bit_range!(self.flags, u32, u8, 2, 0) + } + + /// Sets the `target_integrity_risk_tir_level` bitrange of `flags`. + pub fn set_target_integrity_risk_tir_level(&mut self, target_integrity_risk_tir_level: u8) { + set_bit_range!( + &mut self.flags, + target_integrity_risk_tir_level, + u32, + u8, + 2, + 0 + ); + } + + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 17, 15).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u32, u8, 17, 15); + } + + /// Gets the [InertialNavigationMode][self::InertialNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InertialNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InertialNavigationMode` were added. + pub fn inertial_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 19, 18).try_into() + } + + /// Set the bitrange corresponding to the [InertialNavigationMode][InertialNavigationMode] of the `flags` bitfield. + pub fn set_inertial_navigation_mode( + &mut self, + inertial_navigation_mode: InertialNavigationMode, + ) { + set_bit_range!(&mut self.flags, inertial_navigation_mode, u32, u8, 19, 18); + } + + /// Gets the [TimeStatus][self::TimeStatus] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeStatus` were added. + pub fn time_status(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 20, 20).try_into() + } + + /// Set the bitrange corresponding to the [TimeStatus][TimeStatus] of the `flags` bitfield. + pub fn set_time_status(&mut self, time_status: TimeStatus) { + set_bit_range!(&mut self.flags, time_status, u32, u8, 20, 20); + } + + /// Gets the `velocity_valid` flag. + pub fn velocity_valid(&self) -> bool { + ((self.flags >> 21) & 1) == 1 + } + + /// Sets the `velocity_valid` flag. + pub fn set_velocity_valid(&mut self, velocity_valid: bool) { + self.flags ^= (!(velocity_valid as u32)) & (1 << 21) + } + + /// Gets the `attitude_valid` flag. + pub fn attitude_valid(&self) -> bool { + ((self.flags >> 22) & 1) == 1 + } + + /// Sets the `attitude_valid` flag. + pub fn set_attitude_valid(&mut self, attitude_valid: bool) { + self.flags ^= (!(attitude_valid as u32)) & (1 << 22) + } + + /// Gets the `safe_state_hpl` flag. + pub fn safe_state_hpl(&self) -> bool { + ((self.flags >> 23) & 1) == 1 + } + + /// Sets the `safe_state_hpl` flag. + pub fn set_safe_state_hpl(&mut self, safe_state_hpl: bool) { + self.flags ^= (!(safe_state_hpl as u32)) & (1 << 23) + } + + /// Gets the `safe_state_vpl` flag. + pub fn safe_state_vpl(&self) -> bool { + ((self.flags >> 24) & 1) == 1 + } + + /// Sets the `safe_state_vpl` flag. + pub fn set_safe_state_vpl(&mut self, safe_state_vpl: bool) { + self.flags ^= (!(safe_state_vpl as u32)) & (1 << 24) + } + + /// Gets the `safe_state_atpl` flag. + pub fn safe_state_atpl(&self) -> bool { + ((self.flags >> 25) & 1) == 1 + } + + /// Sets the `safe_state_atpl` flag. + pub fn set_safe_state_atpl(&mut self, safe_state_atpl: bool) { + self.flags ^= (!(safe_state_atpl as u32)) & (1 << 25) + } + + /// Gets the `safe_state_ctpl` flag. + pub fn safe_state_ctpl(&self) -> bool { + ((self.flags >> 26) & 1) == 1 + } + + /// Sets the `safe_state_ctpl` flag. + pub fn set_safe_state_ctpl(&mut self, safe_state_ctpl: bool) { + self.flags ^= (!(safe_state_ctpl as u32)) & (1 << 26) + } + + /// Gets the `safe_state_hvpl` flag. + pub fn safe_state_hvpl(&self) -> bool { + ((self.flags >> 27) & 1) == 1 + } + + /// Sets the `safe_state_hvpl` flag. + pub fn set_safe_state_hvpl(&mut self, safe_state_hvpl: bool) { + self.flags ^= (!(safe_state_hvpl as u32)) & (1 << 27) + } + + /// Gets the `safe_state_vvpl` flag. + pub fn safe_state_vvpl(&self) -> bool { + ((self.flags >> 28) & 1) == 1 + } + + /// Sets the `safe_state_vvpl` flag. + pub fn set_safe_state_vvpl(&mut self, safe_state_vvpl: bool) { + self.flags ^= (!(safe_state_vvpl as u32)) & (1 << 28) + } + + /// Gets the `safe_state_hopl` flag. + pub fn safe_state_hopl(&self) -> bool { + ((self.flags >> 29) & 1) == 1 + } + + /// Sets the `safe_state_hopl` flag. + pub fn set_safe_state_hopl(&mut self, safe_state_hopl: bool) { + self.flags ^= (!(safe_state_hopl as u32)) & (1 << 29) + } + + /// Gets the `safe_state_popl` flag. + pub fn safe_state_popl(&self) -> bool { + ((self.flags >> 30) & 1) == 1 + } + + /// Sets the `safe_state_popl` flag. + pub fn set_safe_state_popl(&mut self, safe_state_popl: bool) { + self.flags ^= (!(safe_state_popl as u32)) & (1 << 30) + } + + /// Gets the `safe_state_ropl` flag. + pub fn safe_state_ropl(&self) -> bool { + ((self.flags >> 31) & 1) == 1 + } + + /// Sets the `safe_state_ropl` flag. + pub fn set_safe_state_ropl(&mut self, safe_state_ropl: bool) { + self.flags ^= (!(safe_state_ropl as u32)) & (1 << 31) + } + } + + impl ConcreteMessage for MsgProtectionLevel { + const MESSAGE_TYPE: u16 = 535; + const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL"; + } + + impl SbpMessage for MsgProtectionLevel { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + #[allow(clippy::useless_conversion)] + let wn: i16 = match self.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgProtectionLevel { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgProtectionLevel(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgProtectionLevel { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.wn) + + WireFormat::len(&self.hpl) + + WireFormat::len(&self.vpl) + + WireFormat::len(&self.atpl) + + WireFormat::len(&self.ctpl) + + WireFormat::len(&self.hvpl) + + WireFormat::len(&self.vvpl) + + WireFormat::len(&self.hopl) + + WireFormat::len(&self.popl) + + WireFormat::len(&self.ropl) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.v_x) + + WireFormat::len(&self.v_y) + + WireFormat::len(&self.v_z) + + WireFormat::len(&self.roll) + + WireFormat::len(&self.pitch) + + WireFormat::len(&self.heading) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.wn, buf); + WireFormat::write(&self.hpl, buf); + WireFormat::write(&self.vpl, buf); + WireFormat::write(&self.atpl, buf); + WireFormat::write(&self.ctpl, buf); + WireFormat::write(&self.hvpl, buf); + WireFormat::write(&self.vvpl, buf); + WireFormat::write(&self.hopl, buf); + WireFormat::write(&self.popl, buf); + WireFormat::write(&self.ropl, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.v_x, buf); + WireFormat::write(&self.v_y, buf); + WireFormat::write(&self.v_z, buf); + WireFormat::write(&self.roll, buf); + WireFormat::write(&self.pitch, buf); + WireFormat::write(&self.heading, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgProtectionLevel { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + wn: WireFormat::parse_unchecked(buf), + hpl: WireFormat::parse_unchecked(buf), + vpl: WireFormat::parse_unchecked(buf), + atpl: WireFormat::parse_unchecked(buf), + ctpl: WireFormat::parse_unchecked(buf), + hvpl: WireFormat::parse_unchecked(buf), + vvpl: WireFormat::parse_unchecked(buf), + hopl: WireFormat::parse_unchecked(buf), + popl: WireFormat::parse_unchecked(buf), + ropl: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + v_x: WireFormat::parse_unchecked(buf), + v_y: WireFormat::parse_unchecked(buf), + v_z: WireFormat::parse_unchecked(buf), + roll: WireFormat::parse_unchecked(buf), + pitch: WireFormat::parse_unchecked(buf), + heading: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Single Point Position (SPP) + SinglePointPosition = 1, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, + + /// Dead Reckoning + DeadReckoning = 5, + + /// SBAS Position + SbasPosition = 6, + } + + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + FixMode::DeadReckoning => f.write_str("Dead Reckoning"), + FixMode::SbasPosition => f.write_str("SBAS Position"), + } + } + } + + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 1 => Ok(FixMode::SinglePointPosition), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + 5 => Ok(FixMode::DeadReckoning), + 6 => Ok(FixMode::SbasPosition), + i => Err(i), + } + } + } + + /// Inertial Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InertialNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, + } + + impl std::fmt::Display for InertialNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InertialNavigationMode::None => f.write_str("None"), + InertialNavigationMode::InsUsed => f.write_str("INS used"), + } + } + } + + impl TryFrom for InertialNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InertialNavigationMode::None), + 1 => Ok(InertialNavigationMode::InsUsed), + i => Err(i), + } + } + } + + /// Time status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeStatus { + /// GNSS time of validity + GnssTimeOfValidity = 0, + + /// Other + Other = 1, + } + + impl std::fmt::Display for TimeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeStatus::GnssTimeOfValidity => f.write_str("GNSS time of validity"), + TimeStatus::Other => f.write_str("Other"), + } + } + } + + impl TryFrom for TimeStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeStatus::GnssTimeOfValidity), + 1 => Ok(TimeStatus::Other), + i => Err(i), + } + } + } +} + +pub mod msg_protection_level_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Computed Position and Protection Level + /// + /// This message reports the local vertical and horizontal protection levels + /// associated with a given LLH position solution. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgProtectionLevelDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Vertical protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "vpl")))] + pub vpl: u16, + /// Horizontal protection level + #[cfg_attr(feature = "serde", serde(rename(serialize = "hpl")))] + pub hpl: u16, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgProtectionLevelDepA { + /// Gets the [TargetIntegrityRiskTirLevel][self::TargetIntegrityRiskTirLevel] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TargetIntegrityRiskTirLevel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TargetIntegrityRiskTirLevel` were added. + pub fn target_integrity_risk_tir_level(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TargetIntegrityRiskTirLevel][TargetIntegrityRiskTirLevel] of the `flags` bitfield. + pub fn set_target_integrity_risk_tir_level( + &mut self, + target_integrity_risk_tir_level: TargetIntegrityRiskTirLevel, + ) { + set_bit_range!( + &mut self.flags, + target_integrity_risk_tir_level, + u8, + u8, + 2, + 0 + ); + } + } + + impl ConcreteMessage for MsgProtectionLevelDepA { + const MESSAGE_TYPE: u16 = 534; + const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL_DEP_A"; + } + + impl SbpMessage for MsgProtectionLevelDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgProtectionLevelDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgProtectionLevelDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgProtectionLevelDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.vpl) + + WireFormat::len(&self.hpl) + + WireFormat::len(&self.lat) + + WireFormat::len(&self.lon) + + WireFormat::len(&self.height) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.vpl, buf); + WireFormat::write(&self.hpl, buf); + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgProtectionLevelDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + vpl: WireFormat::parse_unchecked(buf), + hpl: WireFormat::parse_unchecked(buf), + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Target Integrity Risk (TIR) Level + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TargetIntegrityRiskTirLevel { + /// Safe state, protection level shall not be used for safety-critical + /// application + SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication = 0, + + /// TIR Level 1 + TirLevel1 = 1, + + /// TIR Level 2 + TirLevel2 = 2, + + /// TIR Level 3 + TirLevel3 = 3, + } + + impl std::fmt::Display for TargetIntegrityRiskTirLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TargetIntegrityRiskTirLevel::SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication => f.write_str("Safe state, protection level shall not be used for safety-critical application"), + TargetIntegrityRiskTirLevel::TirLevel1 => f.write_str("TIR Level 1"), + TargetIntegrityRiskTirLevel::TirLevel2 => f.write_str("TIR Level 2"), + TargetIntegrityRiskTirLevel::TirLevel3 => f.write_str("TIR Level 3"), + } + } + } + + impl TryFrom for TargetIntegrityRiskTirLevel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok( TargetIntegrityRiskTirLevel :: SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication ), + 1 => Ok( TargetIntegrityRiskTirLevel :: TirLevel1 ), + 2 => Ok( TargetIntegrityRiskTirLevel :: TirLevel2 ), + 3 => Ok( TargetIntegrityRiskTirLevel :: TirLevel3 ), + i => Err(i), + } + } + } +} + +pub mod msg_utc_time { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// UTC Time + /// + /// This message reports the Universal Coordinated Time (UTC). Note the flags + /// which indicate the source of the UTC offset value and source of the time + /// fix. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgUtcTime { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Indicates source and time validity + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Year + #[cfg_attr(feature = "serde", serde(rename(serialize = "year")))] + pub year: u16, + /// Month (range 1 .. 12) + #[cfg_attr(feature = "serde", serde(rename(serialize = "month")))] + pub month: u8, + /// days in the month (range 1-31) + #[cfg_attr(feature = "serde", serde(rename(serialize = "day")))] + pub day: u8, + /// hours of day (range 0-23) + #[cfg_attr(feature = "serde", serde(rename(serialize = "hours")))] + pub hours: u8, + /// minutes of hour (range 0-59) + #[cfg_attr(feature = "serde", serde(rename(serialize = "minutes")))] + pub minutes: u8, + /// seconds of minute (range 0-60) rounded down + #[cfg_attr(feature = "serde", serde(rename(serialize = "seconds")))] + pub seconds: u8, + /// nanoseconds of second (range 0-999999999) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns")))] + pub ns: u32, + } + + impl MsgUtcTime { + /// Gets the [UtcOffsetSource][self::UtcOffsetSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `UtcOffsetSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `UtcOffsetSource` were added. + pub fn utc_offset_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [UtcOffsetSource][UtcOffsetSource] of the `flags` bitfield. + pub fn set_utc_offset_source(&mut self, utc_offset_source: UtcOffsetSource) { + set_bit_range!(&mut self.flags, utc_offset_source, u8, u8, 4, 3); + } + + /// Gets the [TimeSource][self::TimeSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeSource` were added. + pub fn time_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeSource][TimeSource] of the `flags` bitfield. + pub fn set_time_source(&mut self, time_source: TimeSource) { + set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgUtcTime { + const MESSAGE_TYPE: u16 = 259; + const MESSAGE_NAME: &'static str = "MSG_UTC_TIME"; + } + + impl SbpMessage for MsgUtcTime { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgUtcTime { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgUtcTime(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgUtcTime { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.year) + + WireFormat::len(&self.month) + + WireFormat::len(&self.day) + + WireFormat::len(&self.hours) + + WireFormat::len(&self.minutes) + + WireFormat::len(&self.seconds) + + WireFormat::len(&self.ns) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.year, buf); + WireFormat::write(&self.month, buf); + WireFormat::write(&self.day, buf); + WireFormat::write(&self.hours, buf); + WireFormat::write(&self.minutes, buf); + WireFormat::write(&self.seconds, buf); + WireFormat::write(&self.ns, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgUtcTime { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + year: WireFormat::parse_unchecked(buf), + month: WireFormat::parse_unchecked(buf), + day: WireFormat::parse_unchecked(buf), + hours: WireFormat::parse_unchecked(buf), + minutes: WireFormat::parse_unchecked(buf), + seconds: WireFormat::parse_unchecked(buf), + ns: WireFormat::parse_unchecked(buf), + } + } + } + + /// UTC offset source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum UtcOffsetSource { + /// Factory Default + FactoryDefault = 0, + + /// Non Volatile Memory + NonVolatileMemory = 1, + + /// Decoded this Session + DecodedThisSession = 2, + } + + impl std::fmt::Display for UtcOffsetSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UtcOffsetSource::FactoryDefault => f.write_str("Factory Default"), + UtcOffsetSource::NonVolatileMemory => f.write_str("Non Volatile Memory"), + UtcOffsetSource::DecodedThisSession => f.write_str("Decoded this Session"), + } + } + } + + impl TryFrom for UtcOffsetSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(UtcOffsetSource::FactoryDefault), + 1 => Ok(UtcOffsetSource::NonVolatileMemory), + 2 => Ok(UtcOffsetSource::DecodedThisSession), + i => Err(i), + } + } + } + + /// Time source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeSource { + /// None (invalid) + None = 0, + + /// GNSS Solution + GnssSolution = 1, + + /// Propagated + Propagated = 2, + } + + impl std::fmt::Display for TimeSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeSource::None => f.write_str("None (invalid)"), + TimeSource::GnssSolution => f.write_str("GNSS Solution"), + TimeSource::Propagated => f.write_str("Propagated"), + } + } + } + + impl TryFrom for TimeSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeSource::None), + 1 => Ok(TimeSource::GnssSolution), + 2 => Ok(TimeSource::Propagated), + i => Err(i), + } + } + } +} + +pub mod msg_utc_time_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// UTC Time + /// + /// This message reports the Universal Coordinated Time (UTC). Note the flags + /// which indicate the source of the UTC offset value and source of the time + /// fix. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgUtcTimeGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Indicates source and time validity + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Year + #[cfg_attr(feature = "serde", serde(rename(serialize = "year")))] + pub year: u16, + /// Month (range 1 .. 12) + #[cfg_attr(feature = "serde", serde(rename(serialize = "month")))] + pub month: u8, + /// days in the month (range 1-31) + #[cfg_attr(feature = "serde", serde(rename(serialize = "day")))] + pub day: u8, + /// hours of day (range 0-23) + #[cfg_attr(feature = "serde", serde(rename(serialize = "hours")))] + pub hours: u8, + /// minutes of hour (range 0-59) + #[cfg_attr(feature = "serde", serde(rename(serialize = "minutes")))] + pub minutes: u8, + /// seconds of minute (range 0-60) rounded down + #[cfg_attr(feature = "serde", serde(rename(serialize = "seconds")))] + pub seconds: u8, + /// nanoseconds of second (range 0-999999999) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ns")))] + pub ns: u32, + } + + impl MsgUtcTimeGnss { + /// Gets the [UtcOffsetSource][self::UtcOffsetSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `UtcOffsetSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `UtcOffsetSource` were added. + pub fn utc_offset_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [UtcOffsetSource][UtcOffsetSource] of the `flags` bitfield. + pub fn set_utc_offset_source(&mut self, utc_offset_source: UtcOffsetSource) { + set_bit_range!(&mut self.flags, utc_offset_source, u8, u8, 4, 3); + } + + /// Gets the [TimeSource][self::TimeSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeSource` were added. + pub fn time_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeSource][TimeSource] of the `flags` bitfield. + pub fn set_time_source(&mut self, time_source: TimeSource) { + set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgUtcTimeGnss { + const MESSAGE_TYPE: u16 = 261; + const MESSAGE_NAME: &'static str = "MSG_UTC_TIME_GNSS"; + } + + impl SbpMessage for MsgUtcTimeGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgUtcTimeGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgUtcTimeGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgUtcTimeGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.year) + + WireFormat::len(&self.month) + + WireFormat::len(&self.day) + + WireFormat::len(&self.hours) + + WireFormat::len(&self.minutes) + + WireFormat::len(&self.seconds) + + WireFormat::len(&self.ns) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.year, buf); + WireFormat::write(&self.month, buf); + WireFormat::write(&self.day, buf); + WireFormat::write(&self.hours, buf); + WireFormat::write(&self.minutes, buf); + WireFormat::write(&self.seconds, buf); + WireFormat::write(&self.ns, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgUtcTimeGnss { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + year: WireFormat::parse_unchecked(buf), + month: WireFormat::parse_unchecked(buf), + day: WireFormat::parse_unchecked(buf), + hours: WireFormat::parse_unchecked(buf), + minutes: WireFormat::parse_unchecked(buf), + seconds: WireFormat::parse_unchecked(buf), + ns: WireFormat::parse_unchecked(buf), + } + } + } + + /// UTC offset source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum UtcOffsetSource { + /// Factory Default + FactoryDefault = 0, + + /// Non Volatile Memory + NonVolatileMemory = 1, + + /// Decoded this Session + DecodedThisSession = 2, + } + + impl std::fmt::Display for UtcOffsetSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UtcOffsetSource::FactoryDefault => f.write_str("Factory Default"), + UtcOffsetSource::NonVolatileMemory => f.write_str("Non Volatile Memory"), + UtcOffsetSource::DecodedThisSession => f.write_str("Decoded this Session"), + } } } -} -impl WireFormat for MsgBaselineNedDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineNedDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for UtcOffsetSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(UtcOffsetSource::FactoryDefault), + 1 => Ok(UtcOffsetSource::NonVolatileMemory), + 2 => Ok(UtcOffsetSource::DecodedThisSession), + i => Err(i), + } } } -} -/// Dilution of Precision -/// -/// This dilution of precision (DOP) message describes the effect of -/// navigation satellite geometry on positional measurement precision. The -/// flags field indicated whether the DOP reported corresponds to differential -/// or SPP solution. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgDops { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Geometric Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "gdop")))] - pub gdop: u16, - /// Position Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] - pub pdop: u16, - /// Time Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "tdop")))] - pub tdop: u16, - /// Horizontal Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] - pub hdop: u16, - /// Vertical Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] - pub vdop: u16, - /// Indicates the position solution with which the DOPS message corresponds - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Time source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeSource { + /// None (invalid) + None = 0, -impl ConcreteMessage for MsgDops { - const MESSAGE_TYPE: u16 = 520; - const MESSAGE_NAME: &'static str = "MSG_DOPS"; -} + /// GNSS Solution + GnssSolution = 1, -impl SbpMessage for MsgDops { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Propagated + Propagated = 2, } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgDops { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgDops(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for TimeSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeSource::None => f.write_str("None (invalid)"), + TimeSource::GnssSolution => f.write_str("GNSS Solution"), + TimeSource::Propagated => f.write_str("Propagated"), + } } } -} -impl WireFormat for MsgDops { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.gdop) - + WireFormat::len(&self.pdop) - + WireFormat::len(&self.tdop) - + WireFormat::len(&self.hdop) - + WireFormat::len(&self.vdop) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.gdop, buf); - WireFormat::write(&self.pdop, buf); - WireFormat::write(&self.tdop, buf); - WireFormat::write(&self.hdop, buf); - WireFormat::write(&self.vdop, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgDops { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - gdop: WireFormat::parse_unchecked(buf), - pdop: WireFormat::parse_unchecked(buf), - tdop: WireFormat::parse_unchecked(buf), - hdop: WireFormat::parse_unchecked(buf), - vdop: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for TimeSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeSource::None), + 1 => Ok(TimeSource::GnssSolution), + 2 => Ok(TimeSource::Propagated), + i => Err(i), + } } } } -/// Dilution of Precision -/// -/// This dilution of precision (DOP) message describes the effect of -/// navigation satellite geometry on positional measurement precision. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgDopsDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Geometric Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "gdop")))] - pub gdop: u16, - /// Position Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] - pub pdop: u16, - /// Time Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "tdop")))] - pub tdop: u16, - /// Horizontal Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] - pub hdop: u16, - /// Vertical Dilution of Precision - #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] - pub vdop: u16, -} +pub mod msg_vel_body { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in User Frame + /// + /// This message reports the velocity in the Vehicle Body Frame. By + /// convention, the x-axis should point out the nose of the vehicle and + /// represent the forward direction, while as the y-axis should point out the + /// right hand side of the vehicle. Since this is a right handed system, z + /// should point out the bottom of the vehicle. The orientation and origin of + /// the Vehicle Body Frame are specified via the device settings. The full GPS + /// time is given by the preceding MSG_GPS_TIME with the matching time-of-week + /// (tow). This message is only produced by inertial versions of Swift + /// products and is not available from Piksi Multi or Duro. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelBody { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity in x direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity in y direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity in z direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Estimated variance of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] + pub cov_x_x: f32, + /// Covariance of x and y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] + pub cov_x_y: f32, + /// Covariance of x and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] + pub cov_x_z: f32, + /// Estimated variance of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] + pub cov_y_y: f32, + /// Covariance of y and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] + pub cov_y_z: f32, + /// Estimated variance of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] + pub cov_z_z: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelBody { + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } -impl ConcreteMessage for MsgDopsDepA { - const MESSAGE_TYPE: u16 = 518; - const MESSAGE_NAME: &'static str = "MSG_DOPS_DEP_A"; -} + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3); + } -impl SbpMessage for MsgDopsDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelBody { + const MESSAGE_TYPE: u16 = 531; + const MESSAGE_NAME: &'static str = "MSG_VEL_BODY"; } -} -impl TryFrom for MsgDopsDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgDopsDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelBody { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgDopsDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.gdop) - + WireFormat::len(&self.pdop) - + WireFormat::len(&self.tdop) - + WireFormat::len(&self.hdop) - + WireFormat::len(&self.vdop) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.gdop, buf); - WireFormat::write(&self.pdop, buf); - WireFormat::write(&self.tdop, buf); - WireFormat::write(&self.hdop, buf); - WireFormat::write(&self.vdop, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgDopsDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - gdop: WireFormat::parse_unchecked(buf), - pdop: WireFormat::parse_unchecked(buf), - tdop: WireFormat::parse_unchecked(buf), - hdop: WireFormat::parse_unchecked(buf), - vdop: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelBody { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelBody(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// GPS Time -/// -/// This message reports the GPS time, representing the time since the GPS -/// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and -/// seconds of the week. The weeks begin at the Saturday/Sunday transition. -/// GPS week 0 began at the beginning of the GPS time scale. -/// -/// Within each week number, the GPS time of the week is between between 0 and -/// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap -/// seconds, and as of now, has a small offset from UTC. In a message stream, -/// this message precedes a set of other navigation messages referenced to the -/// same time (but lacking the ns field) and indicates a more precise time of -/// these messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGpsTime { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to - /// 500000) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] - pub ns_residual: i32, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl WireFormat for MsgVelBody { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.cov_x_x) + + WireFormat::len(&self.cov_x_y) + + WireFormat::len(&self.cov_x_z) + + WireFormat::len(&self.cov_y_y) + + WireFormat::len(&self.cov_y_z) + + WireFormat::len(&self.cov_z_z) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.cov_x_x, buf); + WireFormat::write(&self.cov_x_y, buf); + WireFormat::write(&self.cov_x_z, buf); + WireFormat::write(&self.cov_y_y, buf); + WireFormat::write(&self.cov_y_z, buf); + WireFormat::write(&self.cov_z_z, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelBody { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + cov_x_x: WireFormat::parse_unchecked(buf), + cov_x_y: WireFormat::parse_unchecked(buf), + cov_x_z: WireFormat::parse_unchecked(buf), + cov_y_y: WireFormat::parse_unchecked(buf), + cov_y_z: WireFormat::parse_unchecked(buf), + cov_z_z: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgGpsTime { - const MESSAGE_TYPE: u16 = 258; - const MESSAGE_NAME: &'static str = "MSG_GPS_TIME"; -} + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, -impl SbpMessage for MsgGpsTime { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// INS used + InsUsed = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - #[allow(clippy::useless_conversion)] - let wn: i16 = match self.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgGpsTime { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGpsTime(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgGpsTime { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.wn) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.ns_residual) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.wn, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.ns_residual, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGpsTime { - sender_id: None, - wn: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - ns_residual: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// GPS Time (v1.0) -/// -/// This message reports the GPS time, representing the time since the GPS -/// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and -/// seconds of the week. The weeks begin at the Saturday/Sunday transition. -/// GPS week 0 began at the beginning of the GPS time scale. -/// -/// Within each week number, the GPS time of the week is between between 0 and -/// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap -/// seconds, and as of now, has a small offset from UTC. In a message stream, -/// this message precedes a set of other navigation messages referenced to the -/// same time (but lacking the ns field) and indicates a more precise time of -/// these messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGpsTimeDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to - /// 500000) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] - pub ns_residual: i32, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgGpsTimeDepA { - const MESSAGE_TYPE: u16 = 256; - const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_DEP_A"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgGpsTimeDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - #[allow(clippy::useless_conversion)] - let wn: i16 = match self.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgGpsTimeDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGpsTimeDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgGpsTimeDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.wn) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.ns_residual) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.wn, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.ns_residual, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGpsTimeDepA { - sender_id: None, - wn: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - ns_residual: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// GPS Time -/// -/// This message reports the GPS time, representing the time since the GPS -/// epoch began on midnight January 6, 1980 UTC. GPS time counts the weeks and -/// seconds of the week. The weeks begin at the Saturday/Sunday transition. -/// GPS week 0 began at the beginning of the GPS time scale. -/// -/// Within each week number, the GPS time of the week is between between 0 and -/// 604800 seconds (=60*60*24*7). Note that GPS time does not accumulate leap -/// seconds, and as of now, has a small offset from UTC. In a message stream, -/// this message precedes a set of other navigation messages referenced to the -/// same time (but lacking the ns field) and indicates a more precise time of -/// these messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGpsTimeGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: u16, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to - /// 500000) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns_residual")))] - pub ns_residual: i32, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_vel_cog { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity expressed as course over ground + /// + /// This message reports the receiver course over ground (COG) and speed over + /// ground (SOG) based on the horizontal (N-E) components of the NED velocity + /// vector. It also includes the vertical velocity coordinate. A flag is + /// provided to indicate whether the COG value has been frozen. When the flag + /// is set to true, the COG field is set to its last valid value until the + /// system exceeds a minimum velocity threshold. No other fields are affected + /// by this flag. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is + /// given by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// Note: course over ground represents the receiver's direction of travel, + /// but not necessarily the device heading. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelCog { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Course over ground relative to north direction + #[cfg_attr(feature = "serde", serde(rename(serialize = "cog")))] + pub cog: u32, + /// Speed over ground (based on horizontal velocity) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sog")))] + pub sog: u32, + /// Vertical velocity component (positive up) + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_up")))] + pub v_up: i32, + /// Course over ground estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "cog_accuracy")))] + pub cog_accuracy: u32, + /// Speed over ground estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "sog_accuracy")))] + pub sog_accuracy: u32, + /// Vertical velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_up_accuracy")))] + pub v_up_accuracy: u32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u16, + } + + impl MsgVelCog { + /// Gets the [CogFrozen][self::CogFrozen] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CogFrozen` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CogFrozen` were added. + pub fn cog_frozen(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 9, 9).try_into() + } -impl ConcreteMessage for MsgGpsTimeGnss { - const MESSAGE_TYPE: u16 = 260; - const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_GNSS"; -} + /// Set the bitrange corresponding to the [CogFrozen][CogFrozen] of the `flags` bitfield. + pub fn set_cog_frozen(&mut self, cog_frozen: CogFrozen) { + set_bit_range!(&mut self.flags, cog_frozen, u16, u8, 9, 9); + } -impl SbpMessage for MsgGpsTimeGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - #[allow(clippy::useless_conversion)] - let wn: i16 = match self.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} + /// Gets the [VerticalVelocityValidity][self::VerticalVelocityValidity] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VerticalVelocityValidity` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VerticalVelocityValidity` were added. + pub fn vertical_velocity_validity(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 8, 8).try_into() + } -impl TryFrom for MsgGpsTimeGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGpsTimeGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Set the bitrange corresponding to the [VerticalVelocityValidity][VerticalVelocityValidity] of the `flags` bitfield. + pub fn set_vertical_velocity_validity( + &mut self, + vertical_velocity_validity: VerticalVelocityValidity, + ) { + set_bit_range!(&mut self.flags, vertical_velocity_validity, u16, u8, 8, 8); } - } -} -impl WireFormat for MsgGpsTimeGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.wn) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.ns_residual) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.wn, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.ns_residual, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGpsTimeGnss { - sender_id: None, - wn: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - ns_residual: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + /// Gets the [SogValidity][self::SogValidity] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SogValidity` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SogValidity` were added. + pub fn sog_validity(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 7, 7).try_into() } - } -} -/// Single-point position in ECEF -/// -/// The position solution message reports absolute Earth Centered Earth Fixed -/// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of -/// the position solution. If the rover receiver knows the surveyed position -/// of the base station and has an RTK solution, this reports a pseudo- -/// absolute position solution using the base station position and the rover's -/// RTK baseline vector. The full GPS time is given by the preceding -/// MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosEcef { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, - /// Position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Set the bitrange corresponding to the [SogValidity][SogValidity] of the `flags` bitfield. + pub fn set_sog_validity(&mut self, sog_validity: SogValidity) { + set_bit_range!(&mut self.flags, sog_validity, u16, u8, 7, 7); + } -impl ConcreteMessage for MsgPosEcef { - const MESSAGE_TYPE: u16 = 521; - const MESSAGE_NAME: &'static str = "MSG_POS_ECEF"; -} + /// Gets the [CogValidity][self::CogValidity] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CogValidity` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CogValidity` were added. + pub fn cog_validity(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 6, 6).try_into() + } -impl SbpMessage for MsgPosEcef { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} + /// Set the bitrange corresponding to the [CogValidity][CogValidity] of the `flags` bitfield. + pub fn set_cog_validity(&mut self, cog_validity: CogValidity) { + set_bit_range!(&mut self.flags, cog_validity, u16, u8, 6, 6); + } -impl TryFrom for MsgPosEcef { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosEcef(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 5, 5).try_into() } - } -} -impl WireFormat for MsgPosEcef { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosEcef { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u16, u8, 5, 5); } - } -} -/// Single-point position in ECEF -/// -/// The position solution message reports absolute Earth Centered Earth Fixed -/// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of -/// the position solution. The message also reports the upper triangular -/// portion of the 3x3 covariance matrix. If the receiver knows the surveyed -/// position of the base station and has an RTK solution, this reports a -/// pseudo-absolute position solution using the base station position and the -/// rover's RTK baseline vector. The full GPS time is given by the preceding -/// MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosEcefCov { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, - /// Estimated variance of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] - pub cov_x_x: f32, - /// Estimated covariance of x and y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] - pub cov_x_y: f32, - /// Estimated covariance of x and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] - pub cov_x_z: f32, - /// Estimated variance of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] - pub cov_y_y: f32, - /// Estimated covariance of y and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] - pub cov_y_z: f32, - /// Estimated variance of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] - pub cov_z_z: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 4, 3).try_into() + } -impl ConcreteMessage for MsgPosEcefCov { - const MESSAGE_TYPE: u16 = 532; - const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV"; -} + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u16, u8, 4, 3); + } -impl SbpMessage for MsgPosEcefCov { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u16, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelCog { + const MESSAGE_TYPE: u16 = 540; + const MESSAGE_NAME: &'static str = "MSG_VEL_COG"; } -} -impl TryFrom for MsgPosEcefCov { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosEcefCov(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelCog { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgPosEcefCov { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.cov_x_x) - + WireFormat::len(&self.cov_x_y) - + WireFormat::len(&self.cov_x_z) - + WireFormat::len(&self.cov_y_y) - + WireFormat::len(&self.cov_y_z) - + WireFormat::len(&self.cov_z_z) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.cov_x_x, buf); - WireFormat::write(&self.cov_x_y, buf); - WireFormat::write(&self.cov_x_z, buf); - WireFormat::write(&self.cov_y_y, buf); - WireFormat::write(&self.cov_y_z, buf); - WireFormat::write(&self.cov_z_z, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosEcefCov { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - cov_x_x: WireFormat::parse_unchecked(buf), - cov_x_y: WireFormat::parse_unchecked(buf), - cov_x_z: WireFormat::parse_unchecked(buf), - cov_y_y: WireFormat::parse_unchecked(buf), - cov_y_z: WireFormat::parse_unchecked(buf), - cov_z_z: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelCog { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelCog(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// GNSS-only Position in ECEF -/// -/// The position solution message reports absolute Earth Centered Earth Fixed -/// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of -/// the position solution. The message also reports the upper triangular -/// portion of the 3x3 covariance matrix. If the receiver knows the surveyed -/// position of the base station and has an RTK solution, this reports a -/// pseudo-absolute position solution using the base station position and the -/// rover's RTK baseline vector. The full GPS time is given by the preceding -/// MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosEcefCovGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, - /// Estimated variance of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] - pub cov_x_x: f32, - /// Estimated covariance of x and y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] - pub cov_x_y: f32, - /// Estimated covariance of x and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] - pub cov_x_z: f32, - /// Estimated variance of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] - pub cov_y_y: f32, - /// Estimated covariance of y and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] - pub cov_y_z: f32, - /// Estimated variance of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] - pub cov_z_z: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl WireFormat for MsgVelCog { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.cog) + + WireFormat::len(&self.sog) + + WireFormat::len(&self.v_up) + + WireFormat::len(&self.cog_accuracy) + + WireFormat::len(&self.sog_accuracy) + + WireFormat::len(&self.v_up_accuracy) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.cog, buf); + WireFormat::write(&self.sog, buf); + WireFormat::write(&self.v_up, buf); + WireFormat::write(&self.cog_accuracy, buf); + WireFormat::write(&self.sog_accuracy, buf); + WireFormat::write(&self.v_up_accuracy, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelCog { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + cog: WireFormat::parse_unchecked(buf), + sog: WireFormat::parse_unchecked(buf), + v_up: WireFormat::parse_unchecked(buf), + cog_accuracy: WireFormat::parse_unchecked(buf), + sog_accuracy: WireFormat::parse_unchecked(buf), + v_up_accuracy: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgPosEcefCovGnss { - const MESSAGE_TYPE: u16 = 564; - const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV_GNSS"; -} + /// COG frozen + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CogFrozen { + /// Not frozen + NotFrozen = 0, -impl SbpMessage for MsgPosEcefCovGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Frozen + Frozen = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgPosEcefCovGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosEcefCovGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for CogFrozen { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CogFrozen::NotFrozen => f.write_str("Not frozen"), + CogFrozen::Frozen => f.write_str("Frozen"), + } } } -} -impl WireFormat for MsgPosEcefCovGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.cov_x_x) - + WireFormat::len(&self.cov_x_y) - + WireFormat::len(&self.cov_x_z) - + WireFormat::len(&self.cov_y_y) - + WireFormat::len(&self.cov_y_z) - + WireFormat::len(&self.cov_z_z) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.cov_x_x, buf); - WireFormat::write(&self.cov_x_y, buf); - WireFormat::write(&self.cov_x_z, buf); - WireFormat::write(&self.cov_y_y, buf); - WireFormat::write(&self.cov_y_z, buf); - WireFormat::write(&self.cov_z_z, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosEcefCovGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - cov_x_x: WireFormat::parse_unchecked(buf), - cov_x_y: WireFormat::parse_unchecked(buf), - cov_x_z: WireFormat::parse_unchecked(buf), - cov_y_y: WireFormat::parse_unchecked(buf), - cov_y_z: WireFormat::parse_unchecked(buf), - cov_z_z: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for CogFrozen { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CogFrozen::NotFrozen), + 1 => Ok(CogFrozen::Frozen), + i => Err(i), + } } } -} - -/// Single-point position in ECEF -/// -/// The position solution message reports absolute Earth Centered Earth Fixed -/// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of -/// the position solution. If the rover receiver knows the surveyed position -/// of the base station and has an RTK solution, this reports a pseudo- -/// absolute position solution using the base station position and the rover's -/// RTK baseline vector. The full GPS time is given by the preceding -/// MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosEcefDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, - /// Position accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} -impl ConcreteMessage for MsgPosEcefDepA { - const MESSAGE_TYPE: u16 = 512; - const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_DEP_A"; -} + /// Vertical velocity validity + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VerticalVelocityValidity { + /// Invalid + Invalid = 0, -impl SbpMessage for MsgPosEcefDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Vertical velocity valid + VerticalVelocityValid = 1, } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgPosEcefDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosEcefDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VerticalVelocityValidity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VerticalVelocityValidity::Invalid => f.write_str("Invalid"), + VerticalVelocityValidity::VerticalVelocityValid => { + f.write_str("Vertical velocity valid") + } + } } } -} -impl WireFormat for MsgPosEcefDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosEcefDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VerticalVelocityValidity { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VerticalVelocityValidity::Invalid), + 1 => Ok(VerticalVelocityValidity::VerticalVelocityValid), + i => Err(i), + } } } -} -/// GNSS-only Position in ECEF -/// -/// The position solution message reports absolute Earth Centered Earth Fixed -/// (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of -/// the position solution. If the rover receiver knows the surveyed position -/// of the base station and has an RTK solution, this reports a pseudo- -/// absolute position solution using the base station position and the rover's -/// RTK baseline vector. The full GPS time is given by the preceding -/// MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosEcefGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, - /// Position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} - -impl ConcreteMessage for MsgPosEcefGnss { - const MESSAGE_TYPE: u16 = 553; - const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_GNSS"; -} + /// SOG validity + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SogValidity { + /// Invalid + Invalid = 0, -impl SbpMessage for MsgPosEcefGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// SOG valid + SogValid = 1, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgPosEcefGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosEcefGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for SogValidity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SogValidity::Invalid => f.write_str("Invalid"), + SogValidity::SogValid => f.write_str("SOG valid"), + } } } -} -impl WireFormat for MsgPosEcefGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosEcefGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for SogValidity { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SogValidity::Invalid), + 1 => Ok(SogValidity::SogValid), + i => Err(i), + } } } -} -/// Geodetic Position -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution. If the rover receiver knows the surveyed position of the base -/// station and has an RTK solution, this reports a pseudo-absolute position -/// solution using the base station position and the rover's RTK baseline -/// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the -/// matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlh { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height above WGS84 ellipsoid - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Horizontal position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// COG validity + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CogValidity { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgPosLlh { - const MESSAGE_TYPE: u16 = 522; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH"; -} + /// COG valid + CogValid = 1, + } -impl SbpMessage for MsgPosLlh { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for CogValidity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CogValidity::Invalid => f.write_str("Invalid"), + CogValidity::CogValid => f.write_str("COG valid"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for CogValidity { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CogValidity::Invalid), + 1 => Ok(CogValidity::CogValid), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, + + /// Other + Other = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, } -} -impl TryFrom for MsgPosLlh { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlh(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgPosLlh { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlh { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// Geodetic Position and Accuracy -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution as well as the estimated horizontal, vertical, cross-track and -/// along-track errors. The position information and Fix Mode flags follow -/// the MSG_POS_LLH message. Since the covariance matrix is computed in the -/// local-level North, East, Down frame, the estimated error terms follow that -/// convention. -/// -/// The estimated errors are reported at a user-configurable confidence level. -/// The user-configured percentile is encoded in the percentile field. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlhAcc { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height above WGS84 ellipsoid - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Height above the geoid (i.e. height above mean sea level). See - /// confidence_and_geoid for geoid model used. - #[cfg_attr(feature = "serde", serde(rename(serialize = "orthometric_height")))] - pub orthometric_height: f64, - /// Estimated horizontal error at the user-configured confidence level; zero - /// implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: f32, - /// Estimated vertical error at the user-configured confidence level; zero - /// implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: f32, - /// Estimated cross-track error at the user-configured confidence level; - /// zero implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "ct_accuracy")))] - pub ct_accuracy: f32, - /// Estimated along-track error at the user-configured confidence level; - /// zero implies invalid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "at_accuracy")))] - pub at_accuracy: f32, - /// The estimated horizontal error ellipse at the user-configured confidence - /// level. - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_ellipse")))] - pub h_ellipse: EstimatedHorizontalErrorEllipse, - /// The lower bits describe the configured confidence level for the - /// estimated position error. The middle bits describe the geoid model used - /// to calculate the orthometric height. - #[cfg_attr(feature = "serde", serde(rename(serialize = "confidence_and_geoid")))] - pub confidence_and_geoid: u8, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgPosLlhAcc { - const MESSAGE_TYPE: u16 = 536; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH_ACC"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgPosLlhAcc { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgPosLlhAcc { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlhAcc(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgPosLlhAcc { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.orthometric_height) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.ct_accuracy) - + WireFormat::len(&self.at_accuracy) - + WireFormat::len(&self.h_ellipse) - + WireFormat::len(&self.confidence_and_geoid) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.orthometric_height, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.ct_accuracy, buf); - WireFormat::write(&self.at_accuracy, buf); - WireFormat::write(&self.h_ellipse, buf); - WireFormat::write(&self.confidence_and_geoid, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlhAcc { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - orthometric_height: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - ct_accuracy: WireFormat::parse_unchecked(buf), - at_accuracy: WireFormat::parse_unchecked(buf), - h_ellipse: WireFormat::parse_unchecked(buf), - confidence_and_geoid: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// Geodetic Position -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution as well as the upper triangle of the 3x3 covariance matrix. The -/// position information and Fix Mode flags follow the MSG_POS_LLH message. -/// Since the covariance matrix is computed in the local-level North, East, -/// Down frame, the covariance terms follow that convention. Thus, covariances -/// are reported against the "downward" measurement and care should be taken -/// with the sign convention. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlhCov { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height above WGS84 ellipsoid - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Estimated variance of northing - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] - pub cov_n_n: f32, - /// Covariance of northing and easting - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] - pub cov_n_e: f32, - /// Covariance of northing and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] - pub cov_n_d: f32, - /// Estimated variance of easting - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] - pub cov_e_e: f32, - /// Covariance of easting and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] - pub cov_e_d: f32, - /// Estimated variance of downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] - pub cov_d_d: f32, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_vel_ecef { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in ECEF + /// + /// This message reports the velocity in Earth Centered Earth Fixed (ECEF) + /// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelEcef { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelEcef { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } -impl ConcreteMessage for MsgPosLlhCov { - const MESSAGE_TYPE: u16 = 529; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV"; -} + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } -impl SbpMessage for MsgPosLlhCov { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelEcef { + const MESSAGE_TYPE: u16 = 525; + const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF"; } -} -impl TryFrom for MsgPosLlhCov { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlhCov(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelEcef { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgPosLlhCov { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.cov_n_n) - + WireFormat::len(&self.cov_n_e) - + WireFormat::len(&self.cov_n_d) - + WireFormat::len(&self.cov_e_e) - + WireFormat::len(&self.cov_e_d) - + WireFormat::len(&self.cov_d_d) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.cov_n_n, buf); - WireFormat::write(&self.cov_n_e, buf); - WireFormat::write(&self.cov_n_d, buf); - WireFormat::write(&self.cov_e_e, buf); - WireFormat::write(&self.cov_e_d, buf); - WireFormat::write(&self.cov_d_d, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlhCov { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - cov_n_n: WireFormat::parse_unchecked(buf), - cov_n_e: WireFormat::parse_unchecked(buf), - cov_n_d: WireFormat::parse_unchecked(buf), - cov_e_e: WireFormat::parse_unchecked(buf), - cov_e_d: WireFormat::parse_unchecked(buf), - cov_d_d: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelEcef { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelEcef(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// GNSS-only Geodetic Position -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution as well as the upper triangle of the 3x3 covariance matrix. The -/// position information and Fix Mode flags should follow the MSG_POS_LLH -/// message. Since the covariance matrix is computed in the local-level -/// North, East, Down frame, the covariance terms follow with that convention. -/// Thus, covariances are reported against the "downward" measurement and care -/// should be taken with the sign convention. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlhCovGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height above WGS84 ellipsoid - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Estimated variance of northing - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] - pub cov_n_n: f32, - /// Covariance of northing and easting - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] - pub cov_n_e: f32, - /// Covariance of northing and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] - pub cov_n_d: f32, - /// Estimated variance of easting - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] - pub cov_e_e: f32, - /// Covariance of easting and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] - pub cov_e_d: f32, - /// Estimated variance of downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] - pub cov_d_d: f32, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl WireFormat for MsgVelEcef { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelEcef { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgPosLlhCovGnss { - const MESSAGE_TYPE: u16 = 561; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV_GNSS"; -} + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, -impl SbpMessage for MsgPosLlhCovGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Other + Other = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, } -} -impl TryFrom for MsgPosLlhCovGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlhCovGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgPosLlhCovGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.cov_n_n) - + WireFormat::len(&self.cov_n_e) - + WireFormat::len(&self.cov_n_d) - + WireFormat::len(&self.cov_e_e) - + WireFormat::len(&self.cov_e_d) - + WireFormat::len(&self.cov_d_d) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.cov_n_n, buf); - WireFormat::write(&self.cov_n_e, buf); - WireFormat::write(&self.cov_n_d, buf); - WireFormat::write(&self.cov_e_e, buf); - WireFormat::write(&self.cov_e_d, buf); - WireFormat::write(&self.cov_d_d, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlhCovGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - cov_n_n: WireFormat::parse_unchecked(buf), - cov_n_e: WireFormat::parse_unchecked(buf), - cov_n_d: WireFormat::parse_unchecked(buf), - cov_e_e: WireFormat::parse_unchecked(buf), - cov_e_d: WireFormat::parse_unchecked(buf), - cov_d_d: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// Geodetic Position -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution. If the rover receiver knows the surveyed position of the base -/// station and has an RTK solution, this reports a pseudo-absolute position -/// solution using the base station position and the rover's RTK baseline -/// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the -/// matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlhDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Horizontal position accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical position accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgPosLlhDepA { - const MESSAGE_TYPE: u16 = 513; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH_DEP_A"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgPosLlhDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgPosLlhDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlhDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgPosLlhDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlhDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// GNSS-only Geodetic Position -/// -/// This position solution message reports the absolute geodetic coordinates -/// and the status (single point vs pseudo-absolute RTK) of the position -/// solution. If the rover receiver knows the surveyed position of the base -/// station and has an RTK solution, this reports a pseudo-absolute position -/// solution using the base station position and the rover's RTK baseline -/// vector. The full GPS time is given by the preceding MSG_GPS_TIME with the -/// matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPosLlhGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height above WGS84 ellipsoid - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Horizontal position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical position estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_vel_ecef_cov { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in ECEF + /// + /// This message reports the velocity in Earth Centered Earth Fixed (ECEF) + /// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelEcefCov { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Estimated variance of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] + pub cov_x_x: f32, + /// Estimated covariance of x and y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] + pub cov_x_y: f32, + /// Estimated covariance of x and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] + pub cov_x_z: f32, + /// Estimated variance of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] + pub cov_y_y: f32, + /// Estimated covariance of y and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] + pub cov_y_z: f32, + /// Estimated variance of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] + pub cov_z_z: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelEcefCov { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } -impl ConcreteMessage for MsgPosLlhGnss { - const MESSAGE_TYPE: u16 = 554; - const MESSAGE_NAME: &'static str = "MSG_POS_LLH_GNSS"; -} + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } -impl SbpMessage for MsgPosLlhGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelEcefCov { + const MESSAGE_TYPE: u16 = 533; + const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV"; } -} -impl TryFrom for MsgPosLlhGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPosLlhGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelEcefCov { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgPosLlhGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPosLlhGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelEcefCov { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelEcefCov(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Computed state and Protection Levels -/// -/// This message reports the protection levels associated to the given state -/// estimate. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgProtectionLevel { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// GPS week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "wn")))] - pub wn: i16, - /// Horizontal protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "hpl")))] - pub hpl: u16, - /// Vertical protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "vpl")))] - pub vpl: u16, - /// Along-track position error protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "atpl")))] - pub atpl: u16, - /// Cross-track position error protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "ctpl")))] - pub ctpl: u16, - /// Protection level for the error vector between estimated and true - /// along/cross track velocity vector - #[cfg_attr(feature = "serde", serde(rename(serialize = "hvpl")))] - pub hvpl: u16, - /// Protection level for the velocity in vehicle upright direction - /// (different from vertical direction if on a slope) - #[cfg_attr(feature = "serde", serde(rename(serialize = "vvpl")))] - pub vvpl: u16, - /// Heading orientation protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "hopl")))] - pub hopl: u16, - /// Pitch orientation protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "popl")))] - pub popl: u16, - /// Roll orientation protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "ropl")))] - pub ropl: u16, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Velocity in vehicle x direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_x")))] - pub v_x: i32, - /// Velocity in vehicle y direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_y")))] - pub v_y: i32, - /// Velocity in vehicle z direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_z")))] - pub v_z: i32, - /// Roll angle - #[cfg_attr(feature = "serde", serde(rename(serialize = "roll")))] - pub roll: i32, - /// Pitch angle - #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch")))] - pub pitch: i32, - /// Heading angle - #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] - pub heading: i32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} + impl WireFormat for MsgVelEcefCov { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.cov_x_x) + + WireFormat::len(&self.cov_x_y) + + WireFormat::len(&self.cov_x_z) + + WireFormat::len(&self.cov_y_y) + + WireFormat::len(&self.cov_y_z) + + WireFormat::len(&self.cov_z_z) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.cov_x_x, buf); + WireFormat::write(&self.cov_x_y, buf); + WireFormat::write(&self.cov_x_z, buf); + WireFormat::write(&self.cov_y_y, buf); + WireFormat::write(&self.cov_y_z, buf); + WireFormat::write(&self.cov_z_z, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelEcefCov { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + cov_x_x: WireFormat::parse_unchecked(buf), + cov_x_y: WireFormat::parse_unchecked(buf), + cov_x_z: WireFormat::parse_unchecked(buf), + cov_y_y: WireFormat::parse_unchecked(buf), + cov_y_z: WireFormat::parse_unchecked(buf), + cov_z_z: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgProtectionLevel { - const MESSAGE_TYPE: u16 = 535; - const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL"; -} + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, -impl SbpMessage for MsgProtectionLevel { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Other + Other = 1, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - #[allow(clippy::useless_conversion)] - let wn: i16 = match self.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, } -} -impl TryFrom for MsgProtectionLevel { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgProtectionLevel(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgProtectionLevel { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.wn) - + WireFormat::len(&self.hpl) - + WireFormat::len(&self.vpl) - + WireFormat::len(&self.atpl) - + WireFormat::len(&self.ctpl) - + WireFormat::len(&self.hvpl) - + WireFormat::len(&self.vvpl) - + WireFormat::len(&self.hopl) - + WireFormat::len(&self.popl) - + WireFormat::len(&self.ropl) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.v_x) - + WireFormat::len(&self.v_y) - + WireFormat::len(&self.v_z) - + WireFormat::len(&self.roll) - + WireFormat::len(&self.pitch) - + WireFormat::len(&self.heading) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.wn, buf); - WireFormat::write(&self.hpl, buf); - WireFormat::write(&self.vpl, buf); - WireFormat::write(&self.atpl, buf); - WireFormat::write(&self.ctpl, buf); - WireFormat::write(&self.hvpl, buf); - WireFormat::write(&self.vvpl, buf); - WireFormat::write(&self.hopl, buf); - WireFormat::write(&self.popl, buf); - WireFormat::write(&self.ropl, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.v_x, buf); - WireFormat::write(&self.v_y, buf); - WireFormat::write(&self.v_z, buf); - WireFormat::write(&self.roll, buf); - WireFormat::write(&self.pitch, buf); - WireFormat::write(&self.heading, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgProtectionLevel { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - wn: WireFormat::parse_unchecked(buf), - hpl: WireFormat::parse_unchecked(buf), - vpl: WireFormat::parse_unchecked(buf), - atpl: WireFormat::parse_unchecked(buf), - ctpl: WireFormat::parse_unchecked(buf), - hvpl: WireFormat::parse_unchecked(buf), - vvpl: WireFormat::parse_unchecked(buf), - hopl: WireFormat::parse_unchecked(buf), - popl: WireFormat::parse_unchecked(buf), - ropl: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - v_x: WireFormat::parse_unchecked(buf), - v_y: WireFormat::parse_unchecked(buf), - v_z: WireFormat::parse_unchecked(buf), - roll: WireFormat::parse_unchecked(buf), - pitch: WireFormat::parse_unchecked(buf), - heading: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// Computed Position and Protection Level -/// -/// This message reports the local vertical and horizontal protection levels -/// associated with a given LLH position solution. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgProtectionLevelDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Vertical protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "vpl")))] - pub vpl: u16, - /// Horizontal protection level - #[cfg_attr(feature = "serde", serde(rename(serialize = "hpl")))] - pub hpl: u16, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgProtectionLevelDepA { - const MESSAGE_TYPE: u16 = 534; - const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL_DEP_A"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgProtectionLevelDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgProtectionLevelDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgProtectionLevelDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgProtectionLevelDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.vpl) - + WireFormat::len(&self.hpl) - + WireFormat::len(&self.lat) - + WireFormat::len(&self.lon) - + WireFormat::len(&self.height) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.vpl, buf); - WireFormat::write(&self.hpl, buf); - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgProtectionLevelDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - vpl: WireFormat::parse_unchecked(buf), - hpl: WireFormat::parse_unchecked(buf), - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// UTC Time -/// -/// This message reports the Universal Coordinated Time (UTC). Note the flags -/// which indicate the source of the UTC offset value and source of the time -/// fix. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgUtcTime { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Indicates source and time validity - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Year - #[cfg_attr(feature = "serde", serde(rename(serialize = "year")))] - pub year: u16, - /// Month (range 1 .. 12) - #[cfg_attr(feature = "serde", serde(rename(serialize = "month")))] - pub month: u8, - /// days in the month (range 1-31) - #[cfg_attr(feature = "serde", serde(rename(serialize = "day")))] - pub day: u8, - /// hours of day (range 0-23) - #[cfg_attr(feature = "serde", serde(rename(serialize = "hours")))] - pub hours: u8, - /// minutes of hour (range 0-59) - #[cfg_attr(feature = "serde", serde(rename(serialize = "minutes")))] - pub minutes: u8, - /// seconds of minute (range 0-60) rounded down - #[cfg_attr(feature = "serde", serde(rename(serialize = "seconds")))] - pub seconds: u8, - /// nanoseconds of second (range 0-999999999) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns")))] - pub ns: u32, -} - -impl ConcreteMessage for MsgUtcTime { - const MESSAGE_TYPE: u16 = 259; - const MESSAGE_NAME: &'static str = "MSG_UTC_TIME"; -} +pub mod msg_vel_ecef_cov_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Velocity in ECEF + /// + /// This message reports the velocity in Earth Centered Earth Fixed (ECEF) + /// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelEcefCovGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Estimated variance of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] + pub cov_x_x: f32, + /// Estimated covariance of x and y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] + pub cov_x_y: f32, + /// Estimated covariance of x and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] + pub cov_x_z: f32, + /// Estimated variance of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] + pub cov_y_y: f32, + /// Estimated covariance of y and z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] + pub cov_y_z: f32, + /// Estimated variance of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] + pub cov_z_z: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelEcefCovGnss { + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } -impl SbpMessage for MsgUtcTime { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgVelEcefCovGnss { + const MESSAGE_TYPE: u16 = 565; + const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV_GNSS"; } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl SbpMessage for MsgVelEcefCovGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgUtcTime { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgUtcTime(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgVelEcefCovGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelEcefCovGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgUtcTime { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.year) - + WireFormat::len(&self.month) - + WireFormat::len(&self.day) - + WireFormat::len(&self.hours) - + WireFormat::len(&self.minutes) - + WireFormat::len(&self.seconds) - + WireFormat::len(&self.ns) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.year, buf); - WireFormat::write(&self.month, buf); - WireFormat::write(&self.day, buf); - WireFormat::write(&self.hours, buf); - WireFormat::write(&self.minutes, buf); - WireFormat::write(&self.seconds, buf); - WireFormat::write(&self.ns, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgUtcTime { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - year: WireFormat::parse_unchecked(buf), - month: WireFormat::parse_unchecked(buf), - day: WireFormat::parse_unchecked(buf), - hours: WireFormat::parse_unchecked(buf), - minutes: WireFormat::parse_unchecked(buf), - seconds: WireFormat::parse_unchecked(buf), - ns: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgVelEcefCovGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.cov_x_x) + + WireFormat::len(&self.cov_x_y) + + WireFormat::len(&self.cov_x_z) + + WireFormat::len(&self.cov_y_y) + + WireFormat::len(&self.cov_y_z) + + WireFormat::len(&self.cov_z_z) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.cov_x_x, buf); + WireFormat::write(&self.cov_x_y, buf); + WireFormat::write(&self.cov_x_z, buf); + WireFormat::write(&self.cov_y_y, buf); + WireFormat::write(&self.cov_y_z, buf); + WireFormat::write(&self.cov_z_z, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelEcefCovGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + cov_x_x: WireFormat::parse_unchecked(buf), + cov_x_y: WireFormat::parse_unchecked(buf), + cov_x_z: WireFormat::parse_unchecked(buf), + cov_y_y: WireFormat::parse_unchecked(buf), + cov_y_z: WireFormat::parse_unchecked(buf), + cov_z_z: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// UTC Time -/// -/// This message reports the Universal Coordinated Time (UTC). Note the flags -/// which indicate the source of the UTC offset value and source of the time -/// fix. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgUtcTimeGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Indicates source and time validity - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Year - #[cfg_attr(feature = "serde", serde(rename(serialize = "year")))] - pub year: u16, - /// Month (range 1 .. 12) - #[cfg_attr(feature = "serde", serde(rename(serialize = "month")))] - pub month: u8, - /// days in the month (range 1-31) - #[cfg_attr(feature = "serde", serde(rename(serialize = "day")))] - pub day: u8, - /// hours of day (range 0-23) - #[cfg_attr(feature = "serde", serde(rename(serialize = "hours")))] - pub hours: u8, - /// minutes of hour (range 0-59) - #[cfg_attr(feature = "serde", serde(rename(serialize = "minutes")))] - pub minutes: u8, - /// seconds of minute (range 0-60) rounded down - #[cfg_attr(feature = "serde", serde(rename(serialize = "seconds")))] - pub seconds: u8, - /// nanoseconds of second (range 0-999999999) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ns")))] - pub ns: u32, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgUtcTimeGnss { - const MESSAGE_TYPE: u16 = 261; - const MESSAGE_NAME: &'static str = "MSG_UTC_TIME_GNSS"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgUtcTimeGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Computed Doppler derived + ComputedDopplerDerived = 2, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + i => Err(i), + } + } } } -impl TryFrom for MsgUtcTimeGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgUtcTimeGnss(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_vel_ecef_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in ECEF + /// + /// This message reports the velocity in Earth Centered Earth Fixed (ECEF) + /// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelEcefDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Velocity accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl ConcreteMessage for MsgVelEcefDepA { + const MESSAGE_TYPE: u16 = 516; + const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_DEP_A"; + } + + impl SbpMessage for MsgVelEcefDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgUtcTimeGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.year) - + WireFormat::len(&self.month) - + WireFormat::len(&self.day) - + WireFormat::len(&self.hours) - + WireFormat::len(&self.minutes) - + WireFormat::len(&self.seconds) - + WireFormat::len(&self.ns) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.year, buf); - WireFormat::write(&self.month, buf); - WireFormat::write(&self.day, buf); - WireFormat::write(&self.hours, buf); - WireFormat::write(&self.minutes, buf); - WireFormat::write(&self.seconds, buf); - WireFormat::write(&self.ns, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgUtcTimeGnss { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - year: WireFormat::parse_unchecked(buf), - month: WireFormat::parse_unchecked(buf), - day: WireFormat::parse_unchecked(buf), - hours: WireFormat::parse_unchecked(buf), - minutes: WireFormat::parse_unchecked(buf), - seconds: WireFormat::parse_unchecked(buf), - ns: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelEcefDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelEcefDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Velocity in User Frame -/// -/// This message reports the velocity in the Vehicle Body Frame. By -/// convention, the x-axis should point out the nose of the vehicle and -/// represent the forward direction, while as the y-axis should point out the -/// right hand side of the vehicle. Since this is a right handed system, z -/// should point out the bottom of the vehicle. The orientation and origin of -/// the Vehicle Body Frame are specified via the device settings. The full GPS -/// time is given by the preceding MSG_GPS_TIME with the matching time-of-week -/// (tow). This message is only produced by inertial versions of Swift -/// products and is not available from Piksi Multi or Duro. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelBody { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity in x direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity in y direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity in z direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Estimated variance of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] - pub cov_x_x: f32, - /// Covariance of x and y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] - pub cov_x_y: f32, - /// Covariance of x and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] - pub cov_x_z: f32, - /// Estimated variance of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] - pub cov_y_y: f32, - /// Covariance of y and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] - pub cov_y_z: f32, - /// Estimated variance of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] - pub cov_z_z: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, + impl WireFormat for MsgVelEcefDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelEcefDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgVelBody { - const MESSAGE_TYPE: u16 = 531; - const MESSAGE_NAME: &'static str = "MSG_VEL_BODY"; -} +pub mod msg_vel_ecef_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Velocity in ECEF + /// + /// This message reports the velocity in Earth Centered Earth Fixed (ECEF) + /// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with + /// the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelEcefGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// Velocity ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// Velocity ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] + pub accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelEcefGnss { + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } -impl SbpMessage for MsgVelBody { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgVelEcefGnss { + const MESSAGE_TYPE: u16 = 557; + const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_GNSS"; } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl SbpMessage for MsgVelEcefGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgVelBody { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelBody(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgVelEcefGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelEcefGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgVelBody { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.cov_x_x) - + WireFormat::len(&self.cov_x_y) - + WireFormat::len(&self.cov_x_z) - + WireFormat::len(&self.cov_y_y) - + WireFormat::len(&self.cov_y_z) - + WireFormat::len(&self.cov_z_z) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.cov_x_x, buf); - WireFormat::write(&self.cov_x_y, buf); - WireFormat::write(&self.cov_x_z, buf); - WireFormat::write(&self.cov_y_y, buf); - WireFormat::write(&self.cov_y_z, buf); - WireFormat::write(&self.cov_z_z, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelBody { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - cov_x_x: WireFormat::parse_unchecked(buf), - cov_x_y: WireFormat::parse_unchecked(buf), - cov_x_z: WireFormat::parse_unchecked(buf), - cov_y_y: WireFormat::parse_unchecked(buf), - cov_y_z: WireFormat::parse_unchecked(buf), - cov_z_z: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgVelEcefGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelEcefGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// Velocity expressed as course over ground -/// -/// This message reports the receiver course over ground (COG) and speed over -/// ground (SOG) based on the horizontal (N-E) components of the NED velocity -/// vector. It also includes the vertical velocity coordinate. A flag is -/// provided to indicate whether the COG value has been frozen. When the flag -/// is set to true, the COG field is set to its last valid value until the -/// system exceeds a minimum velocity threshold. No other fields are affected -/// by this flag. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is -/// given by the preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// Note: course over ground represents the receiver's direction of travel, -/// but not necessarily the device heading. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelCog { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Course over ground relative to north direction - #[cfg_attr(feature = "serde", serde(rename(serialize = "cog")))] - pub cog: u32, - /// Speed over ground (based on horizontal velocity) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sog")))] - pub sog: u32, - /// Vertical velocity component (positive up) - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_up")))] - pub v_up: i32, - /// Course over ground estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "cog_accuracy")))] - pub cog_accuracy: u32, - /// Speed over ground estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "sog_accuracy")))] - pub sog_accuracy: u32, - /// Vertical velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_up_accuracy")))] - pub v_up_accuracy: u32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u16, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgVelCog { - const MESSAGE_TYPE: u16 = 540; - const MESSAGE_NAME: &'static str = "MSG_VEL_COG"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgVelCog { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Computed Doppler derived + ComputedDopplerDerived = 2, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgVelCog { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelCog(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + } } } -} -impl WireFormat for MsgVelCog { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.cog) - + WireFormat::len(&self.sog) - + WireFormat::len(&self.v_up) - + WireFormat::len(&self.cog_accuracy) - + WireFormat::len(&self.sog_accuracy) - + WireFormat::len(&self.v_up_accuracy) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.cog, buf); - WireFormat::write(&self.sog, buf); - WireFormat::write(&self.v_up, buf); - WireFormat::write(&self.cog_accuracy, buf); - WireFormat::write(&self.sog_accuracy, buf); - WireFormat::write(&self.v_up_accuracy, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelCog { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - cog: WireFormat::parse_unchecked(buf), - sog: WireFormat::parse_unchecked(buf), - v_up: WireFormat::parse_unchecked(buf), - cog_accuracy: WireFormat::parse_unchecked(buf), - sog_accuracy: WireFormat::parse_unchecked(buf), - v_up_accuracy: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + i => Err(i), + } } } } -/// Velocity in ECEF -/// -/// This message reports the velocity in Earth Centered Earth Fixed (ECEF) -/// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelEcef { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_vel_ned { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in NED + /// + /// This message reports the velocity in local North East Down (NED) + /// coordinates. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelNed { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Velocity East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Velocity Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Horizontal velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelNed { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } -impl ConcreteMessage for MsgVelEcef { - const MESSAGE_TYPE: u16 = 525; - const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF"; -} + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } -impl SbpMessage for MsgVelEcef { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelNed { + const MESSAGE_TYPE: u16 = 526; + const MESSAGE_NAME: &'static str = "MSG_VEL_NED"; } -} -impl TryFrom for MsgVelEcef { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelEcef(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelNed { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgVelEcef { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelEcef { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelNed { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelNed(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Velocity in ECEF -/// -/// This message reports the velocity in Earth Centered Earth Fixed (ECEF) -/// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelEcefCov { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Estimated variance of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] - pub cov_x_x: f32, - /// Estimated covariance of x and y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] - pub cov_x_y: f32, - /// Estimated covariance of x and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] - pub cov_x_z: f32, - /// Estimated variance of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] - pub cov_y_y: f32, - /// Estimated covariance of y and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] - pub cov_y_z: f32, - /// Estimated variance of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] - pub cov_z_z: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl WireFormat for MsgVelNed { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelNed { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgVelEcefCov { - const MESSAGE_TYPE: u16 = 533; - const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV"; -} + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, -impl SbpMessage for MsgVelEcefCov { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Other + Other = 1, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, } -} -impl TryFrom for MsgVelEcefCov { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelEcefCov(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgVelEcefCov { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.cov_x_x) - + WireFormat::len(&self.cov_x_y) - + WireFormat::len(&self.cov_x_z) - + WireFormat::len(&self.cov_y_y) - + WireFormat::len(&self.cov_y_z) - + WireFormat::len(&self.cov_z_z) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.cov_x_x, buf); - WireFormat::write(&self.cov_x_y, buf); - WireFormat::write(&self.cov_x_z, buf); - WireFormat::write(&self.cov_y_y, buf); - WireFormat::write(&self.cov_y_z, buf); - WireFormat::write(&self.cov_z_z, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelEcefCov { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - cov_x_x: WireFormat::parse_unchecked(buf), - cov_x_y: WireFormat::parse_unchecked(buf), - cov_x_z: WireFormat::parse_unchecked(buf), - cov_y_y: WireFormat::parse_unchecked(buf), - cov_y_z: WireFormat::parse_unchecked(buf), - cov_z_z: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// GNSS-only Velocity in ECEF -/// -/// This message reports the velocity in Earth Centered Earth Fixed (ECEF) -/// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelEcefCovGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Estimated variance of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_x")))] - pub cov_x_x: f32, - /// Estimated covariance of x and y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_y")))] - pub cov_x_y: f32, - /// Estimated covariance of x and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_x_z")))] - pub cov_x_z: f32, - /// Estimated variance of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_y")))] - pub cov_y_y: f32, - /// Estimated covariance of y and z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_y_z")))] - pub cov_y_z: f32, - /// Estimated variance of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_z_z")))] - pub cov_z_z: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgVelEcefCovGnss { - const MESSAGE_TYPE: u16 = 565; - const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV_GNSS"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgVelEcefCovGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgVelEcefCovGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelEcefCovGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgVelEcefCovGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.cov_x_x) - + WireFormat::len(&self.cov_x_y) - + WireFormat::len(&self.cov_x_z) - + WireFormat::len(&self.cov_y_y) - + WireFormat::len(&self.cov_y_z) - + WireFormat::len(&self.cov_z_z) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.cov_x_x, buf); - WireFormat::write(&self.cov_x_y, buf); - WireFormat::write(&self.cov_x_z, buf); - WireFormat::write(&self.cov_y_y, buf); - WireFormat::write(&self.cov_y_z, buf); - WireFormat::write(&self.cov_z_z, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelEcefCovGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - cov_x_x: WireFormat::parse_unchecked(buf), - cov_x_y: WireFormat::parse_unchecked(buf), - cov_x_z: WireFormat::parse_unchecked(buf), - cov_y_y: WireFormat::parse_unchecked(buf), - cov_y_z: WireFormat::parse_unchecked(buf), - cov_z_z: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// Velocity in ECEF -/// -/// This message reports the velocity in Earth Centered Earth Fixed (ECEF) -/// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelEcefDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Velocity accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_vel_ned_cov { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in NED + /// + /// This message reports the velocity in local North East Down (NED) + /// coordinates. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). This + /// message is similar to the MSG_VEL_NED, but it includes the upper + /// triangular portion of the 3x3 covariance matrix. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelNedCov { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Velocity East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Velocity Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Estimated variance of northward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] + pub cov_n_n: f32, + /// Covariance of northward and eastward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] + pub cov_n_e: f32, + /// Covariance of northward and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] + pub cov_n_d: f32, + /// Estimated variance of eastward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] + pub cov_e_e: f32, + /// Covariance of eastward and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] + pub cov_e_d: f32, + /// Estimated variance of downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] + pub cov_d_d: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelNedCov { + /// Gets the [TypeOfReportedTow][self::TypeOfReportedTow] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfReportedTow` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfReportedTow` were added. + pub fn type_of_reported_tow(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 5).try_into() + } -impl ConcreteMessage for MsgVelEcefDepA { - const MESSAGE_TYPE: u16 = 516; - const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_DEP_A"; -} + /// Set the bitrange corresponding to the [TypeOfReportedTow][TypeOfReportedTow] of the `flags` bitfield. + pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) { + set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5); + } -impl SbpMessage for MsgVelEcefDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3); + } + + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgVelNedCov { + const MESSAGE_TYPE: u16 = 530; + const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV"; } -} -impl TryFrom for MsgVelEcefDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelEcefDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgVelNedCov { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgVelEcefDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelEcefDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelNedCov { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelNedCov(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// GNSS-only Velocity in ECEF -/// -/// This message reports the velocity in Earth Centered Earth Fixed (ECEF) -/// coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with -/// the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelEcefGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// Velocity ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// Velocity ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "accuracy")))] - pub accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl WireFormat for MsgVelNedCov { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.cov_n_n) + + WireFormat::len(&self.cov_n_e) + + WireFormat::len(&self.cov_n_d) + + WireFormat::len(&self.cov_e_e) + + WireFormat::len(&self.cov_e_d) + + WireFormat::len(&self.cov_d_d) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.cov_n_n, buf); + WireFormat::write(&self.cov_n_e, buf); + WireFormat::write(&self.cov_n_d, buf); + WireFormat::write(&self.cov_e_e, buf); + WireFormat::write(&self.cov_e_d, buf); + WireFormat::write(&self.cov_d_d, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelNedCov { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + cov_n_n: WireFormat::parse_unchecked(buf), + cov_n_e: WireFormat::parse_unchecked(buf), + cov_n_d: WireFormat::parse_unchecked(buf), + cov_e_e: WireFormat::parse_unchecked(buf), + cov_e_d: WireFormat::parse_unchecked(buf), + cov_d_d: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgVelEcefGnss { - const MESSAGE_TYPE: u16 = 557; - const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_GNSS"; -} + /// Type of reported TOW + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfReportedTow { + /// Time of Measurement + TimeOfMeasurement = 0, -impl SbpMessage for MsgVelEcefGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Other + Other = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TypeOfReportedTow { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"), + TypeOfReportedTow::Other => f.write_str("Other"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TypeOfReportedTow { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfReportedTow::TimeOfMeasurement), + 1 => Ok(TypeOfReportedTow::Other), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// None + None = 0, + + /// INS used + InsUsed = 1, } -} -impl TryFrom for MsgVelEcefGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelEcefGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::None => f.write_str("None"), + InsNavigationMode::InsUsed => f.write_str("INS used"), + } } } -} -impl WireFormat for MsgVelEcefGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelEcefGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::None), + 1 => Ok(InsNavigationMode::InsUsed), + i => Err(i), + } } } -} -/// Velocity in NED -/// -/// This message reports the velocity in local North East Down (NED) -/// coordinates. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelNed { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Velocity East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Velocity Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Horizontal velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgVelNed { - const MESSAGE_TYPE: u16 = 526; - const MESSAGE_NAME: &'static str = "MSG_VEL_NED"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgVelNed { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + /// Computed Doppler derived + ComputedDopplerDerived = 2, + + /// Dead Reckoning + DeadReckoning = 3, } -} -impl TryFrom for MsgVelNed { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelNed(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"), + } } } -} -impl WireFormat for MsgVelNed { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelNed { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + 3 => Ok(VelocityMode::DeadReckoning), + i => Err(i), + } } } } -/// Velocity in NED -/// -/// This message reports the velocity in local North East Down (NED) -/// coordinates. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). This -/// message is similar to the MSG_VEL_NED, but it includes the upper -/// triangular portion of the 3x3 covariance matrix. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelNedCov { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Velocity East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Velocity Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Estimated variance of northward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] - pub cov_n_n: f32, - /// Covariance of northward and eastward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] - pub cov_n_e: f32, - /// Covariance of northward and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] - pub cov_n_d: f32, - /// Estimated variance of eastward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] - pub cov_e_e: f32, - /// Covariance of eastward and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] - pub cov_e_d: f32, - /// Estimated variance of downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] - pub cov_d_d: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} - -impl ConcreteMessage for MsgVelNedCov { - const MESSAGE_TYPE: u16 = 530; - const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV"; -} +pub mod msg_vel_ned_cov_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Velocity in NED + /// + /// This message reports the velocity in local North East Down (NED) + /// coordinates. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). This + /// message is similar to the MSG_VEL_NED, but it includes the upper + /// triangular portion of the 3x3 covariance matrix. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelNedCovGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Velocity East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Velocity Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Estimated variance of northward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] + pub cov_n_n: f32, + /// Covariance of northward and eastward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] + pub cov_n_e: f32, + /// Covariance of northward and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] + pub cov_n_d: f32, + /// Estimated variance of eastward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] + pub cov_e_e: f32, + /// Covariance of eastward and downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] + pub cov_e_d: f32, + /// Estimated variance of downward measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] + pub cov_d_d: f32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelNedCovGnss { + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } -impl SbpMessage for MsgVelNedCov { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgVelNedCovGnss { + const MESSAGE_TYPE: u16 = 562; + const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV_GNSS"; } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl SbpMessage for MsgVelNedCovGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgVelNedCov { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelNedCov(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgVelNedCovGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelNedCovGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgVelNedCov { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.cov_n_n) - + WireFormat::len(&self.cov_n_e) - + WireFormat::len(&self.cov_n_d) - + WireFormat::len(&self.cov_e_e) - + WireFormat::len(&self.cov_e_d) - + WireFormat::len(&self.cov_d_d) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.cov_n_n, buf); - WireFormat::write(&self.cov_n_e, buf); - WireFormat::write(&self.cov_n_d, buf); - WireFormat::write(&self.cov_e_e, buf); - WireFormat::write(&self.cov_e_d, buf); - WireFormat::write(&self.cov_d_d, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelNedCov { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - cov_n_n: WireFormat::parse_unchecked(buf), - cov_n_e: WireFormat::parse_unchecked(buf), - cov_n_d: WireFormat::parse_unchecked(buf), - cov_e_e: WireFormat::parse_unchecked(buf), - cov_e_d: WireFormat::parse_unchecked(buf), - cov_d_d: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgVelNedCovGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.cov_n_n) + + WireFormat::len(&self.cov_n_e) + + WireFormat::len(&self.cov_n_d) + + WireFormat::len(&self.cov_e_e) + + WireFormat::len(&self.cov_e_d) + + WireFormat::len(&self.cov_d_d) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.cov_n_n, buf); + WireFormat::write(&self.cov_n_e, buf); + WireFormat::write(&self.cov_n_d, buf); + WireFormat::write(&self.cov_e_e, buf); + WireFormat::write(&self.cov_e_d, buf); + WireFormat::write(&self.cov_d_d, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelNedCovGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + cov_n_n: WireFormat::parse_unchecked(buf), + cov_n_e: WireFormat::parse_unchecked(buf), + cov_n_d: WireFormat::parse_unchecked(buf), + cov_e_e: WireFormat::parse_unchecked(buf), + cov_e_d: WireFormat::parse_unchecked(buf), + cov_d_d: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// GNSS-only Velocity in NED -/// -/// This message reports the velocity in local North East Down (NED) -/// coordinates. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). This -/// message is similar to the MSG_VEL_NED, but it includes the upper -/// triangular portion of the 3x3 covariance matrix. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelNedCovGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Velocity East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Velocity Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Estimated variance of northward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_n")))] - pub cov_n_n: f32, - /// Covariance of northward and eastward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_e")))] - pub cov_n_e: f32, - /// Covariance of northward and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_n_d")))] - pub cov_n_d: f32, - /// Estimated variance of eastward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_e")))] - pub cov_e_e: f32, - /// Covariance of eastward and downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_e_d")))] - pub cov_e_d: f32, - /// Estimated variance of downward measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "cov_d_d")))] - pub cov_d_d: f32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgVelNedCovGnss { - const MESSAGE_TYPE: u16 = 562; - const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV_GNSS"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgVelNedCovGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Computed Doppler derived + ComputedDopplerDerived = 2, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + i => Err(i), + } + } } } -impl TryFrom for MsgVelNedCovGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelNedCovGnss(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_vel_ned_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Velocity in NED + /// + /// This message reports the velocity in local North East Down (NED) + /// coordinates. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelNedDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Velocity East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Velocity Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Horizontal velocity accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical velocity accuracy estimate (not implemented). Defaults to 0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl ConcreteMessage for MsgVelNedDepA { + const MESSAGE_TYPE: u16 = 517; + const MESSAGE_NAME: &'static str = "MSG_VEL_NED_DEP_A"; + } + + impl SbpMessage for MsgVelNedDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgVelNedCovGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.cov_n_n) - + WireFormat::len(&self.cov_n_e) - + WireFormat::len(&self.cov_n_d) - + WireFormat::len(&self.cov_e_e) - + WireFormat::len(&self.cov_e_d) - + WireFormat::len(&self.cov_d_d) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.cov_n_n, buf); - WireFormat::write(&self.cov_n_e, buf); - WireFormat::write(&self.cov_n_d, buf); - WireFormat::write(&self.cov_e_e, buf); - WireFormat::write(&self.cov_e_d, buf); - WireFormat::write(&self.cov_d_d, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelNedCovGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - cov_n_n: WireFormat::parse_unchecked(buf), - cov_n_e: WireFormat::parse_unchecked(buf), - cov_n_d: WireFormat::parse_unchecked(buf), - cov_e_e: WireFormat::parse_unchecked(buf), - cov_e_d: WireFormat::parse_unchecked(buf), - cov_d_d: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgVelNedDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelNedDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Velocity in NED -/// -/// This message reports the velocity in local North East Down (NED) -/// coordinates. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelNedDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Velocity East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Velocity Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Horizontal velocity accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical velocity accuracy estimate (not implemented). Defaults to 0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, + impl WireFormat for MsgVelNedDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelNedDepA { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgVelNedDepA { - const MESSAGE_TYPE: u16 = 517; - const MESSAGE_NAME: &'static str = "MSG_VEL_NED_DEP_A"; -} +pub mod msg_vel_ned_gnss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// GNSS-only Velocity in NED + /// + /// This message reports the velocity in local North East Down (NED) + /// coordinates. The NED coordinate system is defined as the local WGS84 + /// tangent plane centered at the current position. The full GPS time is given + /// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgVelNedGnss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Velocity North coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] + pub n: i32, + /// Velocity East coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] + pub e: i32, + /// Velocity Down coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] + pub d: i32, + /// Horizontal velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] + pub h_accuracy: u16, + /// Vertical velocity estimated standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] + pub v_accuracy: u16, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgVelNedGnss { + /// Gets the [VelocityMode][self::VelocityMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocityMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocityMode` were added. + pub fn velocity_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } -impl SbpMessage for MsgVelNedDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Set the bitrange corresponding to the [VelocityMode][VelocityMode] of the `flags` bitfield. + pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) { + set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgVelNedGnss { + const MESSAGE_TYPE: u16 = 558; + const MESSAGE_NAME: &'static str = "MSG_VEL_NED_GNSS"; } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl SbpMessage for MsgVelNedGnss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgVelNedDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelNedDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgVelNedGnss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgVelNedGnss(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgVelNedDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelNedDepA { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgVelNedGnss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.n) + + WireFormat::len(&self.e) + + WireFormat::len(&self.d) + + WireFormat::len(&self.h_accuracy) + + WireFormat::len(&self.v_accuracy) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.n, buf); + WireFormat::write(&self.e, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.h_accuracy, buf); + WireFormat::write(&self.v_accuracy, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgVelNedGnss { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + n: WireFormat::parse_unchecked(buf), + e: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + h_accuracy: WireFormat::parse_unchecked(buf), + v_accuracy: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// GNSS-only Velocity in NED -/// -/// This message reports the velocity in local North East Down (NED) -/// coordinates. The NED coordinate system is defined as the local WGS84 -/// tangent plane centered at the current position. The full GPS time is given -/// by the preceding MSG_GPS_TIME with the matching time-of-week (tow). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgVelNedGnss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Velocity North coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "n")))] - pub n: i32, - /// Velocity East coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "e")))] - pub e: i32, - /// Velocity Down coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "d")))] - pub d: i32, - /// Horizontal velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "h_accuracy")))] - pub h_accuracy: u16, - /// Vertical velocity estimated standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "v_accuracy")))] - pub v_accuracy: u16, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Velocity mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocityMode { + /// Invalid + Invalid = 0, -impl ConcreteMessage for MsgVelNedGnss { - const MESSAGE_TYPE: u16 = 558; - const MESSAGE_NAME: &'static str = "MSG_VEL_NED_GNSS"; -} + /// Measured Doppler derived + MeasuredDopplerDerived = 1, -impl SbpMessage for MsgVelNedGnss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Computed Doppler derived + ComputedDopplerDerived = 2, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgVelNedGnss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgVelNedGnss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for VelocityMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocityMode::Invalid => f.write_str("Invalid"), + VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"), + VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"), + } } } -} -impl WireFormat for MsgVelNedGnss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.n) - + WireFormat::len(&self.e) - + WireFormat::len(&self.d) - + WireFormat::len(&self.h_accuracy) - + WireFormat::len(&self.v_accuracy) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.n, buf); - WireFormat::write(&self.e, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.h_accuracy, buf); - WireFormat::write(&self.v_accuracy, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgVelNedGnss { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - n: WireFormat::parse_unchecked(buf), - e: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - h_accuracy: WireFormat::parse_unchecked(buf), - v_accuracy: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for VelocityMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocityMode::Invalid), + 1 => Ok(VelocityMode::MeasuredDopplerDerived), + 2 => Ok(VelocityMode::ComputedDopplerDerived), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/ndb.rs b/rust/sbp/src/messages/ndb.rs index 5b7d263d74..dd61324f30 100644 --- a/rust/sbp/src/messages/ndb.rs +++ b/rust/sbp/src/messages/ndb.rs @@ -13,127 +13,400 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Messages for logging NDB events. +pub use msg_ndb_event::MsgNdbEvent; + +pub mod msg_ndb_event { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Navigation DataBase Event + /// + /// This message is sent out when an object is stored into NDB. If needed + /// message could also be sent out when fetching an object from NDB. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNdbEvent { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// HW time in milliseconds. + #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] + pub recv_time: u64, + /// Event type. + #[cfg_attr(feature = "serde", serde(rename(serialize = "event")))] + pub event: u8, + /// Event object type. + #[cfg_attr(feature = "serde", serde(rename(serialize = "object_type")))] + pub object_type: u8, + /// Event result. + #[cfg_attr(feature = "serde", serde(rename(serialize = "result")))] + pub result: u8, + /// Data source for STORE event, reserved for other events. + #[cfg_attr(feature = "serde", serde(rename(serialize = "data_source")))] + pub data_source: u8, + /// GNSS signal identifier, If object_type is Ephemeris OR Almanac, sid + /// indicates for which signal the object belongs to. Reserved in other + /// cases. + #[cfg_attr(feature = "serde", serde(rename(serialize = "object_sid")))] + pub object_sid: GnssSignal, + /// GNSS signal identifier, If object_type is Almanac, Almanac WN, Iono OR + /// L2C capabilities AND data_source is NDB_DS_RECEIVER sid indicates from + /// which SV data was decoded. Reserved in other cases. + #[cfg_attr(feature = "serde", serde(rename(serialize = "src_sid")))] + pub src_sid: GnssSignal, + /// A unique identifier of the sending hardware. For v1.0, set to the 2 + /// least significant bytes of the device serial number, valid only if + /// data_source is NDB_DS_SBP. Reserved in case of other data_source. + #[cfg_attr(feature = "serde", serde(rename(serialize = "original_sender")))] + pub original_sender: u16, + } + + impl MsgNdbEvent { + /// Gets the [EventType][self::EventType] stored in the `event` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `EventType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `EventType` were added. + pub fn event_type(&self) -> Result { + get_bit_range!(self.event, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [EventType][EventType] of the `event` bitfield. + pub fn set_event_type(&mut self, event_type: EventType) { + set_bit_range!(&mut self.event, event_type, u8, u8, 1, 0); + } + + /// Gets the [EventObjectType][self::EventObjectType] stored in the `object_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `EventObjectType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `EventObjectType` were added. + pub fn event_object_type(&self) -> Result { + get_bit_range!(self.object_type, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [EventObjectType][EventObjectType] of the `object_type` bitfield. + pub fn set_event_object_type(&mut self, event_object_type: EventObjectType) { + set_bit_range!(&mut self.object_type, event_object_type, u8, u8, 2, 0); + } + + /// Gets the [EventResult][self::EventResult] stored in the `result` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `EventResult` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `EventResult` were added. + pub fn event_result(&self) -> Result { + get_bit_range!(self.result, u8, u8, 3, 0).try_into() + } + + /// Set the bitrange corresponding to the [EventResult][EventResult] of the `result` bitfield. + pub fn set_event_result(&mut self, event_result: EventResult) { + set_bit_range!(&mut self.result, event_result, u8, u8, 3, 0); + } + + /// Gets the [DataSource][self::DataSource] stored in the `data_source` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `DataSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `DataSource` were added. + pub fn data_source(&self) -> Result { + get_bit_range!(self.data_source, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [DataSource][DataSource] of the `data_source` bitfield. + pub fn set_data_source(&mut self, data_source: DataSource) { + set_bit_range!(&mut self.data_source, data_source, u8, u8, 1, 0); + } + } + + impl ConcreteMessage for MsgNdbEvent { + const MESSAGE_TYPE: u16 = 1024; + const MESSAGE_NAME: &'static str = "MSG_NDB_EVENT"; + } + + impl SbpMessage for MsgNdbEvent { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgNdbEvent { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNdbEvent(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgNdbEvent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.recv_time) + + WireFormat::len(&self.event) + + WireFormat::len(&self.object_type) + + WireFormat::len(&self.result) + + WireFormat::len(&self.data_source) + + WireFormat::len(&self.object_sid) + + WireFormat::len(&self.src_sid) + + WireFormat::len(&self.original_sender) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.recv_time, buf); + WireFormat::write(&self.event, buf); + WireFormat::write(&self.object_type, buf); + WireFormat::write(&self.result, buf); + WireFormat::write(&self.data_source, buf); + WireFormat::write(&self.object_sid, buf); + WireFormat::write(&self.src_sid, buf); + WireFormat::write(&self.original_sender, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgNdbEvent { + sender_id: None, + recv_time: WireFormat::parse_unchecked(buf), + event: WireFormat::parse_unchecked(buf), + object_type: WireFormat::parse_unchecked(buf), + result: WireFormat::parse_unchecked(buf), + data_source: WireFormat::parse_unchecked(buf), + object_sid: WireFormat::parse_unchecked(buf), + src_sid: WireFormat::parse_unchecked(buf), + original_sender: WireFormat::parse_unchecked(buf), + } + } + } -use super::gnss::*; - -use super::lib::*; - -/// Navigation DataBase Event -/// -/// This message is sent out when an object is stored into NDB. If needed -/// message could also be sent out when fetching an object from NDB. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNdbEvent { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// HW time in milliseconds. - #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] - pub recv_time: u64, /// Event type. - #[cfg_attr(feature = "serde", serde(rename(serialize = "event")))] - pub event: u8, + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum EventType { + /// UNKNOWN + UNKNOWN = 0, + + /// STORE + STORE = 1, + + /// FETCH + FETCH = 2, + + /// ERASE + ERASE = 3, + } + + impl std::fmt::Display for EventType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EventType::UNKNOWN => f.write_str("UNKNOWN"), + EventType::STORE => f.write_str("STORE"), + EventType::FETCH => f.write_str("FETCH"), + EventType::ERASE => f.write_str("ERASE"), + } + } + } + + impl TryFrom for EventType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(EventType::UNKNOWN), + 1 => Ok(EventType::STORE), + 2 => Ok(EventType::FETCH), + 3 => Ok(EventType::ERASE), + i => Err(i), + } + } + } + /// Event object type. - #[cfg_attr(feature = "serde", serde(rename(serialize = "object_type")))] - pub object_type: u8, - /// Event result. - #[cfg_attr(feature = "serde", serde(rename(serialize = "result")))] - pub result: u8, - /// Data source for STORE event, reserved for other events. - #[cfg_attr(feature = "serde", serde(rename(serialize = "data_source")))] - pub data_source: u8, - /// GNSS signal identifier, If object_type is Ephemeris OR Almanac, sid - /// indicates for which signal the object belongs to. Reserved in other - /// cases. - #[cfg_attr(feature = "serde", serde(rename(serialize = "object_sid")))] - pub object_sid: GnssSignal, - /// GNSS signal identifier, If object_type is Almanac, Almanac WN, Iono OR - /// L2C capabilities AND data_source is NDB_DS_RECEIVER sid indicates from - /// which SV data was decoded. Reserved in other cases. - #[cfg_attr(feature = "serde", serde(rename(serialize = "src_sid")))] - pub src_sid: GnssSignal, - /// A unique identifier of the sending hardware. For v1.0, set to the 2 - /// least significant bytes of the device serial number, valid only if - /// data_source is NDB_DS_SBP. Reserved in case of other data_source. - #[cfg_attr(feature = "serde", serde(rename(serialize = "original_sender")))] - pub original_sender: u16, -} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum EventObjectType { + /// UNKNOWN + UNKNOWN = 0, -impl ConcreteMessage for MsgNdbEvent { - const MESSAGE_TYPE: u16 = 1024; - const MESSAGE_NAME: &'static str = "MSG_NDB_EVENT"; -} + /// EPHEMERIS + EPHEMERIS = 1, + + /// ALMANAC + ALMANAC = 2, -impl SbpMessage for MsgNdbEvent { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// ALMANAC_WN + AlmanacWn = 3, + + /// IONO + IoNO = 4, + + /// L2C_CAP + L2CCap = 5, + + /// LGF + LGF = 6, + } + + impl std::fmt::Display for EventObjectType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EventObjectType::UNKNOWN => f.write_str("UNKNOWN"), + EventObjectType::EPHEMERIS => f.write_str("EPHEMERIS"), + EventObjectType::ALMANAC => f.write_str("ALMANAC"), + EventObjectType::AlmanacWn => f.write_str("ALMANAC_WN"), + EventObjectType::IoNO => f.write_str("IONO"), + EventObjectType::L2CCap => f.write_str("L2C_CAP"), + EventObjectType::LGF => f.write_str("LGF"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for EventObjectType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(EventObjectType::UNKNOWN), + 1 => Ok(EventObjectType::EPHEMERIS), + 2 => Ok(EventObjectType::ALMANAC), + 3 => Ok(EventObjectType::AlmanacWn), + 4 => Ok(EventObjectType::IoNO), + 5 => Ok(EventObjectType::L2CCap), + 6 => Ok(EventObjectType::LGF), + i => Err(i), + } + } + } + + /// Event result. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum EventResult { + /// NDB_ERR_NONE + NdbErrNone = 0, + + /// NDB_ERR_MISSING_IE + NdbErrMissingIe = 1, + + /// NDB_ERR_UNSUPPORTED + NdbErrUnsupported = 2, + + /// NDB_ERR_FILE_IO + NdbErrFileIo = 3, + + /// NDB_ERR_INIT_DONE + NdbErrInitDone = 4, + + /// NDB_ERR_BAD_PARAM + NdbErrBadParam = 5, + + /// NDB_ERR_UNRELIABLE_DATA + NdbErrUnreliableData = 6, + + /// NDB_ERR_ALGORITHM_ERROR + NdbErrAlgorithmError = 7, + + /// NDB_ERR_NO_DATA + NdbErrNoData = 8, + + /// NDB_ERR_NO_CHANGE + NdbErrNoChange = 9, + + /// NDB_ERR_OLDER_DATA + NdbErrOlderData = 10, } - fn sender_id(&self) -> Option { - self.sender_id + + impl std::fmt::Display for EventResult { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EventResult::NdbErrNone => f.write_str("NDB_ERR_NONE"), + EventResult::NdbErrMissingIe => f.write_str("NDB_ERR_MISSING_IE"), + EventResult::NdbErrUnsupported => f.write_str("NDB_ERR_UNSUPPORTED"), + EventResult::NdbErrFileIo => f.write_str("NDB_ERR_FILE_IO"), + EventResult::NdbErrInitDone => f.write_str("NDB_ERR_INIT_DONE"), + EventResult::NdbErrBadParam => f.write_str("NDB_ERR_BAD_PARAM"), + EventResult::NdbErrUnreliableData => f.write_str("NDB_ERR_UNRELIABLE_DATA"), + EventResult::NdbErrAlgorithmError => f.write_str("NDB_ERR_ALGORITHM_ERROR"), + EventResult::NdbErrNoData => f.write_str("NDB_ERR_NO_DATA"), + EventResult::NdbErrNoChange => f.write_str("NDB_ERR_NO_CHANGE"), + EventResult::NdbErrOlderData => f.write_str("NDB_ERR_OLDER_DATA"), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for EventResult { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(EventResult::NdbErrNone), + 1 => Ok(EventResult::NdbErrMissingIe), + 2 => Ok(EventResult::NdbErrUnsupported), + 3 => Ok(EventResult::NdbErrFileIo), + 4 => Ok(EventResult::NdbErrInitDone), + 5 => Ok(EventResult::NdbErrBadParam), + 6 => Ok(EventResult::NdbErrUnreliableData), + 7 => Ok(EventResult::NdbErrAlgorithmError), + 8 => Ok(EventResult::NdbErrNoData), + 9 => Ok(EventResult::NdbErrNoChange), + 10 => Ok(EventResult::NdbErrOlderData), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Data source. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum DataSource { + /// NDB_DS_UNDEFINED + NdbDsUndefined = 0, + + /// NDB_DS_INIT + NdbDsInit = 1, + + /// NDB_DS_RECEIVER + NdbDsReceiver = 2, + + /// NDB_DS_SBP + NdbDsSbp = 3, } -} -impl TryFrom for MsgNdbEvent { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNdbEvent(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for DataSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DataSource::NdbDsUndefined => f.write_str("NDB_DS_UNDEFINED"), + DataSource::NdbDsInit => f.write_str("NDB_DS_INIT"), + DataSource::NdbDsReceiver => f.write_str("NDB_DS_RECEIVER"), + DataSource::NdbDsSbp => f.write_str("NDB_DS_SBP"), + } } } -} -impl WireFormat for MsgNdbEvent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.recv_time) - + WireFormat::len(&self.event) - + WireFormat::len(&self.object_type) - + WireFormat::len(&self.result) - + WireFormat::len(&self.data_source) - + WireFormat::len(&self.object_sid) - + WireFormat::len(&self.src_sid) - + WireFormat::len(&self.original_sender) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.recv_time, buf); - WireFormat::write(&self.event, buf); - WireFormat::write(&self.object_type, buf); - WireFormat::write(&self.result, buf); - WireFormat::write(&self.data_source, buf); - WireFormat::write(&self.object_sid, buf); - WireFormat::write(&self.src_sid, buf); - WireFormat::write(&self.original_sender, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgNdbEvent { - sender_id: None, - recv_time: WireFormat::parse_unchecked(buf), - event: WireFormat::parse_unchecked(buf), - object_type: WireFormat::parse_unchecked(buf), - result: WireFormat::parse_unchecked(buf), - data_source: WireFormat::parse_unchecked(buf), - object_sid: WireFormat::parse_unchecked(buf), - src_sid: WireFormat::parse_unchecked(buf), - original_sender: WireFormat::parse_unchecked(buf), + impl TryFrom for DataSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(DataSource::NdbDsUndefined), + 1 => Ok(DataSource::NdbDsInit), + 2 => Ok(DataSource::NdbDsReceiver), + 3 => Ok(DataSource::NdbDsSbp), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/observation.rs b/rust/sbp/src/messages/observation.rs index 7fb1797527..739654829a 100644 --- a/rust/sbp/src/messages/observation.rs +++ b/rust/sbp/src/messages/observation.rs @@ -15,6234 +15,7188 @@ //! Satellite observation messages from the device. The SBP sender ID of 0 //! indicates remote observations from a GNSS base station, correction //! network, or Skylark, Swift's cloud GNSS correction product. - -use super::gnss::*; - -use super::lib::*; - -/// Common fields for every almanac message -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct AlmanacCommonContent { - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Reference time of almanac - #[cfg_attr(feature = "serde", serde(rename(serialize = "toa")))] - pub toa: GpsTimeSec, - /// User Range Accuracy - #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] - pub ura: f64, - /// Curve fit interval - #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] - pub fit_interval: u32, - /// Status of almanac, 1 = valid, 0 = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite health status for GPS: - /// - bits 5-7: NAV data health status. See IS-GPS-200H - /// Table 20-VII: NAV Data Health Indications. - /// - bits 0-4: Signal health status. See IS-GPS-200H - /// Table 20-VIII. Codes for Health of SV Signal - /// Components. - /// Satellite health status for GLO (see GLO ICD 5.1 table 5.1 for details): - /// - bit 0: C(n), "unhealthy" flag that is transmitted within - /// non-immediate data and indicates overall constellation status - /// at the moment of almanac uploading. - /// '0' indicates malfunction of n-satellite. - /// '1' indicates that n-satellite is operational. - /// - bit 1: Bn(ln), '0' indicates the satellite is operational - /// and suitable for navigation. - #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] - pub health_bits: u8, -} - -impl WireFormat for AlmanacCommonContent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.toa) - + WireFormat::len(&self.ura) - + WireFormat::len(&self.fit_interval) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.health_bits) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.toa, buf); - WireFormat::write(&self.ura, buf); - WireFormat::write(&self.fit_interval, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.health_bits, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - AlmanacCommonContent { - sid: WireFormat::parse_unchecked(buf), - toa: WireFormat::parse_unchecked(buf), - ura: WireFormat::parse_unchecked(buf), - fit_interval: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - health_bits: WireFormat::parse_unchecked(buf), +pub use almanac_common_content::AlmanacCommonContent; +pub use almanac_common_content_dep::AlmanacCommonContentDep; +pub use carrier_phase_dep_a::CarrierPhaseDepA; +pub use doppler::Doppler; +pub use ephemeris_common_content::EphemerisCommonContent; +pub use ephemeris_common_content_dep_a::EphemerisCommonContentDepA; +pub use ephemeris_common_content_dep_b::EphemerisCommonContentDepB; +pub use gnss_capb::GnssCapb; +pub use msg_almanac_glo::MsgAlmanacGlo; +pub use msg_almanac_glo_dep::MsgAlmanacGloDep; +pub use msg_almanac_gps::MsgAlmanacGps; +pub use msg_almanac_gps_dep::MsgAlmanacGpsDep; +pub use msg_base_pos_ecef::MsgBasePosEcef; +pub use msg_base_pos_llh::MsgBasePosLlh; +pub use msg_ephemeris_bds::MsgEphemerisBds; +pub use msg_ephemeris_dep_a::MsgEphemerisDepA; +pub use msg_ephemeris_dep_b::MsgEphemerisDepB; +pub use msg_ephemeris_dep_c::MsgEphemerisDepC; +pub use msg_ephemeris_dep_d::MsgEphemerisDepD; +pub use msg_ephemeris_gal::MsgEphemerisGal; +pub use msg_ephemeris_gal_dep_a::MsgEphemerisGalDepA; +pub use msg_ephemeris_glo::MsgEphemerisGlo; +pub use msg_ephemeris_glo_dep_a::MsgEphemerisGloDepA; +pub use msg_ephemeris_glo_dep_b::MsgEphemerisGloDepB; +pub use msg_ephemeris_glo_dep_c::MsgEphemerisGloDepC; +pub use msg_ephemeris_glo_dep_d::MsgEphemerisGloDepD; +pub use msg_ephemeris_gps::MsgEphemerisGps; +pub use msg_ephemeris_gps_dep_e::MsgEphemerisGpsDepE; +pub use msg_ephemeris_gps_dep_f::MsgEphemerisGpsDepF; +pub use msg_ephemeris_qzss::MsgEphemerisQzss; +pub use msg_ephemeris_sbas::MsgEphemerisSbas; +pub use msg_ephemeris_sbas_dep_a::MsgEphemerisSbasDepA; +pub use msg_ephemeris_sbas_dep_b::MsgEphemerisSbasDepB; +pub use msg_glo_biases::MsgGloBiases; +pub use msg_gnss_capb::MsgGnssCapb; +pub use msg_group_delay::MsgGroupDelay; +pub use msg_group_delay_dep_a::MsgGroupDelayDepA; +pub use msg_group_delay_dep_b::MsgGroupDelayDepB; +pub use msg_iono::MsgIono; +pub use msg_obs::MsgObs; +pub use msg_obs_dep_a::MsgObsDepA; +pub use msg_obs_dep_b::MsgObsDepB; +pub use msg_obs_dep_c::MsgObsDepC; +pub use msg_osr::MsgOsr; +pub use msg_sv_az_el::MsgSvAzEl; +pub use msg_sv_configuration_gps_dep::MsgSvConfigurationGpsDep; +pub use observation_header::ObservationHeader; +pub use observation_header_dep::ObservationHeaderDep; +pub use packed_obs_content::PackedObsContent; +pub use packed_obs_content_dep_a::PackedObsContentDepA; +pub use packed_obs_content_dep_b::PackedObsContentDepB; +pub use packed_obs_content_dep_c::PackedObsContentDepC; +pub use packed_osr_content::PackedOsrContent; +pub use sv_az_el::SvAzEl; + +pub mod almanac_common_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Common fields for every almanac message + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct AlmanacCommonContent { + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Reference time of almanac + #[cfg_attr(feature = "serde", serde(rename(serialize = "toa")))] + pub toa: GpsTimeSec, + /// User Range Accuracy + #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] + pub ura: f64, + /// Curve fit interval + #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] + pub fit_interval: u32, + /// Status of almanac, 1 = valid, 0 = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite health status for GPS: + /// - bits 5-7: NAV data health status. See IS-GPS-200H + /// Table 20-VII: NAV Data Health Indications. + /// - bits 0-4: Signal health status. See IS-GPS-200H + /// Table 20-VIII. Codes for Health of SV Signal + /// Components. + /// Satellite health status for GLO (see GLO ICD 5.1 table 5.1 for details): + /// - bit 0: C(n), "unhealthy" flag that is transmitted within + /// non-immediate data and indicates overall constellation status + /// at the moment of almanac uploading. + /// '0' indicates malfunction of n-satellite. + /// '1' indicates that n-satellite is operational. + /// - bit 1: Bn(ln), '0' indicates the satellite is operational + /// and suitable for navigation. + #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] + pub health_bits: u8, + } + + impl WireFormat for AlmanacCommonContent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.toa) + + WireFormat::len(&self.ura) + + WireFormat::len(&self.fit_interval) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.health_bits) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.toa, buf); + WireFormat::write(&self.ura, buf); + WireFormat::write(&self.fit_interval, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.health_bits, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + AlmanacCommonContent { + sid: WireFormat::parse_unchecked(buf), + toa: WireFormat::parse_unchecked(buf), + ura: WireFormat::parse_unchecked(buf), + fit_interval: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + health_bits: WireFormat::parse_unchecked(buf), + } } } } -/// Common fields for every almanac message -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct AlmanacCommonContentDep { - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Reference time of almanac - #[cfg_attr(feature = "serde", serde(rename(serialize = "toa")))] - pub toa: GpsTimeSec, - /// User Range Accuracy - #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] - pub ura: f64, - /// Curve fit interval - #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] - pub fit_interval: u32, - /// Status of almanac, 1 = valid, 0 = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite health status for GPS: - /// - bits 5-7: NAV data health status. See IS-GPS-200H - /// Table 20-VII: NAV Data Health Indications. - /// - bits 0-4: Signal health status. See IS-GPS-200H - /// Table 20-VIII. Codes for Health of SV Signal - /// Components. - /// Satellite health status for GLO (see GLO ICD 5.1 table 5.1 for details): - /// - bit 0: C(n), "unhealthy" flag that is transmitted within - /// non-immediate data and indicates overall constellation status - /// at the moment of almanac uploading. - /// '0' indicates malfunction of n-satellite. - /// '1' indicates that n-satellite is operational. - /// - bit 1: Bn(ln), '0' indicates the satellite is operational - /// and suitable for navigation. - #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] - pub health_bits: u8, +pub mod almanac_common_content_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Common fields for every almanac message + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct AlmanacCommonContentDep { + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Reference time of almanac + #[cfg_attr(feature = "serde", serde(rename(serialize = "toa")))] + pub toa: GpsTimeSec, + /// User Range Accuracy + #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] + pub ura: f64, + /// Curve fit interval + #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] + pub fit_interval: u32, + /// Status of almanac, 1 = valid, 0 = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite health status for GPS: + /// - bits 5-7: NAV data health status. See IS-GPS-200H + /// Table 20-VII: NAV Data Health Indications. + /// - bits 0-4: Signal health status. See IS-GPS-200H + /// Table 20-VIII. Codes for Health of SV Signal + /// Components. + /// Satellite health status for GLO (see GLO ICD 5.1 table 5.1 for details): + /// - bit 0: C(n), "unhealthy" flag that is transmitted within + /// non-immediate data and indicates overall constellation status + /// at the moment of almanac uploading. + /// '0' indicates malfunction of n-satellite. + /// '1' indicates that n-satellite is operational. + /// - bit 1: Bn(ln), '0' indicates the satellite is operational + /// and suitable for navigation. + #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] + pub health_bits: u8, + } + + impl WireFormat for AlmanacCommonContentDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.toa) + + WireFormat::len(&self.ura) + + WireFormat::len(&self.fit_interval) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.health_bits) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.toa, buf); + WireFormat::write(&self.ura, buf); + WireFormat::write(&self.fit_interval, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.health_bits, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + AlmanacCommonContentDep { + sid: WireFormat::parse_unchecked(buf), + toa: WireFormat::parse_unchecked(buf), + ura: WireFormat::parse_unchecked(buf), + fit_interval: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + health_bits: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for AlmanacCommonContentDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.toa) - + WireFormat::len(&self.ura) - + WireFormat::len(&self.fit_interval) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.health_bits) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.toa, buf); - WireFormat::write(&self.ura, buf); - WireFormat::write(&self.fit_interval, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.health_bits, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - AlmanacCommonContentDep { - sid: WireFormat::parse_unchecked(buf), - toa: WireFormat::parse_unchecked(buf), - ura: WireFormat::parse_unchecked(buf), - fit_interval: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - health_bits: WireFormat::parse_unchecked(buf), +pub mod carrier_phase_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GPS carrier phase measurement + /// + /// Carrier phase measurement in cycles represented as a 40-bit fixed point + /// number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of + /// fractional cycles. This has the opposite sign convention than a typical + /// GPS receiver and the phase has the opposite sign as the pseudorange. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct CarrierPhaseDepA { + /// Carrier phase whole cycles + #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] + pub i: i32, + /// Carrier phase fractional part + #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] + pub f: u8, + } + + impl WireFormat for CarrierPhaseDepA { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.i) + WireFormat::len(&self.f) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.i, buf); + WireFormat::write(&self.f, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + CarrierPhaseDepA { + i: WireFormat::parse_unchecked(buf), + f: WireFormat::parse_unchecked(buf), + } } } } -/// GPS carrier phase measurement -/// -/// Carrier phase measurement in cycles represented as a 40-bit fixed point -/// number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of -/// fractional cycles. This has the opposite sign convention than a typical -/// GPS receiver and the phase has the opposite sign as the pseudorange. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct CarrierPhaseDepA { - /// Carrier phase whole cycles - #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] - pub i: i32, - /// Carrier phase fractional part - #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] - pub f: u8, -} +pub mod doppler { + #![allow(unused_imports)] -impl WireFormat for CarrierPhaseDepA { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.i) + WireFormat::len(&self.f) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.i, buf); - WireFormat::write(&self.f, buf); + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GNSS doppler measurement + /// + /// Doppler measurement in Hz represented as a 24-bit fixed point number with + /// Q16.8 layout, i.e. 16-bits of whole doppler and 8-bits of fractional + /// doppler. This doppler is defined as positive for approaching satellites. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct Doppler { + /// Doppler whole Hz + #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] + pub i: i16, + /// Doppler fractional part + #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] + pub f: u8, } - fn parse_unchecked(buf: &mut B) -> Self { - CarrierPhaseDepA { - i: WireFormat::parse_unchecked(buf), - f: WireFormat::parse_unchecked(buf), + + impl WireFormat for Doppler { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.i) + WireFormat::len(&self.f) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.i, buf); + WireFormat::write(&self.f, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + Doppler { + i: WireFormat::parse_unchecked(buf), + f: WireFormat::parse_unchecked(buf), + } } } } -/// GNSS doppler measurement -/// -/// Doppler measurement in Hz represented as a 24-bit fixed point number with -/// Q16.8 layout, i.e. 16-bits of whole doppler and 8-bits of fractional -/// doppler. This doppler is defined as positive for approaching satellites. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct Doppler { - /// Doppler whole Hz - #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] - pub i: i16, - /// Doppler fractional part - #[cfg_attr(feature = "serde", serde(rename(serialize = "f")))] - pub f: u8, -} - -impl WireFormat for Doppler { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.i) + WireFormat::len(&self.f) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.i, buf); - WireFormat::write(&self.f, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - Doppler { - i: WireFormat::parse_unchecked(buf), - f: WireFormat::parse_unchecked(buf), +pub mod ephemeris_common_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Common fields for every ephemeris message + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct EphemerisCommonContent { + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Time of Ephemerides + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] + pub toe: GpsTimeSec, + /// User Range Accuracy + #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] + pub ura: f32, + /// Curve fit interval + #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] + pub fit_interval: u32, + /// Status of ephemeris, 1 = valid, 0 = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite health status. + /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 + /// SBAS: 0 = valid, non-zero = invalid + /// GLO: 0 = valid, non-zero = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] + pub health_bits: u8, + } + + impl WireFormat for EphemerisCommonContent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.toe) + + WireFormat::len(&self.ura) + + WireFormat::len(&self.fit_interval) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.health_bits) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.toe, buf); + WireFormat::write(&self.ura, buf); + WireFormat::write(&self.fit_interval, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.health_bits, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + EphemerisCommonContent { + sid: WireFormat::parse_unchecked(buf), + toe: WireFormat::parse_unchecked(buf), + ura: WireFormat::parse_unchecked(buf), + fit_interval: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + health_bits: WireFormat::parse_unchecked(buf), + } } } } -/// Common fields for every ephemeris message -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct EphemerisCommonContent { - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Time of Ephemerides - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] - pub toe: GpsTimeSec, - /// User Range Accuracy - #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] - pub ura: f32, - /// Curve fit interval - #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] - pub fit_interval: u32, - /// Status of ephemeris, 1 = valid, 0 = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite health status. - /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 - /// SBAS: 0 = valid, non-zero = invalid - /// GLO: 0 = valid, non-zero = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] - pub health_bits: u8, +pub mod ephemeris_common_content_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Common fields for every ephemeris message + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct EphemerisCommonContentDepA { + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Time of Ephemerides + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] + pub toe: GpsTimeDep, + /// User Range Accuracy + #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] + pub ura: f64, + /// Curve fit interval + #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] + pub fit_interval: u32, + /// Status of ephemeris, 1 = valid, 0 = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite health status. + /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 + /// SBAS: 0 = valid, non-zero = invalid + /// GLO: 0 = valid, non-zero = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] + pub health_bits: u8, + } + + impl WireFormat for EphemerisCommonContentDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.toe) + + WireFormat::len(&self.ura) + + WireFormat::len(&self.fit_interval) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.health_bits) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.toe, buf); + WireFormat::write(&self.ura, buf); + WireFormat::write(&self.fit_interval, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.health_bits, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + EphemerisCommonContentDepA { + sid: WireFormat::parse_unchecked(buf), + toe: WireFormat::parse_unchecked(buf), + ura: WireFormat::parse_unchecked(buf), + fit_interval: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + health_bits: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for EphemerisCommonContent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.toe) - + WireFormat::len(&self.ura) - + WireFormat::len(&self.fit_interval) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.health_bits) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.toe, buf); - WireFormat::write(&self.ura, buf); - WireFormat::write(&self.fit_interval, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.health_bits, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - EphemerisCommonContent { - sid: WireFormat::parse_unchecked(buf), - toe: WireFormat::parse_unchecked(buf), - ura: WireFormat::parse_unchecked(buf), - fit_interval: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - health_bits: WireFormat::parse_unchecked(buf), +pub mod ephemeris_common_content_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Common fields for every ephemeris message + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct EphemerisCommonContentDepB { + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Time of Ephemerides + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] + pub toe: GpsTimeSec, + /// User Range Accuracy + #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] + pub ura: f64, + /// Curve fit interval + #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] + pub fit_interval: u32, + /// Status of ephemeris, 1 = valid, 0 = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite health status. + /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 + /// Others: 0 = valid, non-zero = invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] + pub health_bits: u8, + } + + impl WireFormat for EphemerisCommonContentDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.toe) + + WireFormat::len(&self.ura) + + WireFormat::len(&self.fit_interval) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.health_bits) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.toe, buf); + WireFormat::write(&self.ura, buf); + WireFormat::write(&self.fit_interval, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.health_bits, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + EphemerisCommonContentDepB { + sid: WireFormat::parse_unchecked(buf), + toe: WireFormat::parse_unchecked(buf), + ura: WireFormat::parse_unchecked(buf), + fit_interval: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + health_bits: WireFormat::parse_unchecked(buf), + } } } } -/// Common fields for every ephemeris message -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct EphemerisCommonContentDepA { - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Time of Ephemerides - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] - pub toe: GpsTimeDep, - /// User Range Accuracy - #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] - pub ura: f64, - /// Curve fit interval - #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] - pub fit_interval: u32, - /// Status of ephemeris, 1 = valid, 0 = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite health status. - /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 - /// SBAS: 0 = valid, non-zero = invalid - /// GLO: 0 = valid, non-zero = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] - pub health_bits: u8, -} +pub mod gnss_capb { + #![allow(unused_imports)] -impl WireFormat for EphemerisCommonContentDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.toe) - + WireFormat::len(&self.ura) - + WireFormat::len(&self.fit_interval) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.health_bits) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.toe, buf); - WireFormat::write(&self.ura, buf); - WireFormat::write(&self.fit_interval, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.health_bits, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - EphemerisCommonContentDepA { - sid: WireFormat::parse_unchecked(buf), - toe: WireFormat::parse_unchecked(buf), - ura: WireFormat::parse_unchecked(buf), - fit_interval: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - health_bits: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// GNSS capabilities masks + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GnssCapb { + /// GPS SV active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_active")))] + pub gps_active: u64, + /// GPS L2C active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_l2c")))] + pub gps_l2c: u64, + /// GPS L5 active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_l5")))] + pub gps_l5: u64, + /// GLO active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_active")))] + pub glo_active: u32, + /// GLO L2OF active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_l2of")))] + pub glo_l2of: u32, + /// GLO L3 active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_l3")))] + pub glo_l3: u32, + /// SBAS active mask (PRNs 120..158, AN 7/62.2.2-18/18 Table B-23, + /// ) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sbas_active")))] + pub sbas_active: u64, + /// SBAS L5 active mask (PRNs 120..158, AN 7/62.2.2-18/18 Table B-23, + /// ) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sbas_l5")))] + pub sbas_l5: u64, + /// BDS active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_active")))] + pub bds_active: u64, + /// BDS D2NAV active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_d2nav")))] + pub bds_d2nav: u64, + /// BDS B2 active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_b2")))] + pub bds_b2: u64, + /// BDS B2A active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_b2a")))] + pub bds_b2a: u64, + /// QZSS active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "qzss_active")))] + pub qzss_active: u32, + /// GAL active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "gal_active")))] + pub gal_active: u64, + /// GAL E5 active mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "gal_e5")))] + pub gal_e5: u64, + } + + impl WireFormat for GnssCapb { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.gps_active) + + WireFormat::len(&self.gps_l2c) + + WireFormat::len(&self.gps_l5) + + WireFormat::len(&self.glo_active) + + WireFormat::len(&self.glo_l2of) + + WireFormat::len(&self.glo_l3) + + WireFormat::len(&self.sbas_active) + + WireFormat::len(&self.sbas_l5) + + WireFormat::len(&self.bds_active) + + WireFormat::len(&self.bds_d2nav) + + WireFormat::len(&self.bds_b2) + + WireFormat::len(&self.bds_b2a) + + WireFormat::len(&self.qzss_active) + + WireFormat::len(&self.gal_active) + + WireFormat::len(&self.gal_e5) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.gps_active, buf); + WireFormat::write(&self.gps_l2c, buf); + WireFormat::write(&self.gps_l5, buf); + WireFormat::write(&self.glo_active, buf); + WireFormat::write(&self.glo_l2of, buf); + WireFormat::write(&self.glo_l3, buf); + WireFormat::write(&self.sbas_active, buf); + WireFormat::write(&self.sbas_l5, buf); + WireFormat::write(&self.bds_active, buf); + WireFormat::write(&self.bds_d2nav, buf); + WireFormat::write(&self.bds_b2, buf); + WireFormat::write(&self.bds_b2a, buf); + WireFormat::write(&self.qzss_active, buf); + WireFormat::write(&self.gal_active, buf); + WireFormat::write(&self.gal_e5, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GnssCapb { + gps_active: WireFormat::parse_unchecked(buf), + gps_l2c: WireFormat::parse_unchecked(buf), + gps_l5: WireFormat::parse_unchecked(buf), + glo_active: WireFormat::parse_unchecked(buf), + glo_l2of: WireFormat::parse_unchecked(buf), + glo_l3: WireFormat::parse_unchecked(buf), + sbas_active: WireFormat::parse_unchecked(buf), + sbas_l5: WireFormat::parse_unchecked(buf), + bds_active: WireFormat::parse_unchecked(buf), + bds_d2nav: WireFormat::parse_unchecked(buf), + bds_b2: WireFormat::parse_unchecked(buf), + bds_b2a: WireFormat::parse_unchecked(buf), + qzss_active: WireFormat::parse_unchecked(buf), + gal_active: WireFormat::parse_unchecked(buf), + gal_e5: WireFormat::parse_unchecked(buf), + } } } } -/// Common fields for every ephemeris message -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct EphemerisCommonContentDepB { - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Time of Ephemerides - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe")))] - pub toe: GpsTimeSec, - /// User Range Accuracy - #[cfg_attr(feature = "serde", serde(rename(serialize = "ura")))] - pub ura: f64, - /// Curve fit interval - #[cfg_attr(feature = "serde", serde(rename(serialize = "fit_interval")))] - pub fit_interval: u32, - /// Status of ephemeris, 1 = valid, 0 = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite health status. - /// GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 - /// Others: 0 = valid, non-zero = invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "health_bits")))] - pub health_bits: u8, -} +pub mod msg_almanac_glo { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The almanac message returns a set of satellite orbit parameters. Almanac + /// data is not very precise and is considered valid for up to several months. + /// Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and + /// almanac" for details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAlmanacGlo { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all almanac types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: AlmanacCommonContent, + /// Longitude of the first ascending node of the orbit in PZ-90.02 + /// coordinate system + #[cfg_attr(feature = "serde", serde(rename(serialize = "lambda_na")))] + pub lambda_na: f64, + /// Time of the first ascending node passage + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_lambda_na")))] + pub t_lambda_na: f64, + /// Value of inclination at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] + pub i: f64, + /// Value of Draconian period at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: f64, + /// Rate of change of the Draconian period + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_dot")))] + pub t_dot: f64, + /// Eccentricity at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "epsilon")))] + pub epsilon: f64, + /// Argument of perigee at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega")))] + pub omega: f64, + } + + impl ConcreteMessage for MsgAlmanacGlo { + const MESSAGE_TYPE: u16 = 115; + const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GLO"; + } + + impl SbpMessage for MsgAlmanacGlo { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } -impl WireFormat for EphemerisCommonContentDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.toe) - + WireFormat::len(&self.ura) - + WireFormat::len(&self.fit_interval) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.health_bits) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.toe, buf); - WireFormat::write(&self.ura, buf); - WireFormat::write(&self.fit_interval, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.health_bits, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - EphemerisCommonContentDepB { - sid: WireFormat::parse_unchecked(buf), - toe: WireFormat::parse_unchecked(buf), - ura: WireFormat::parse_unchecked(buf), - fit_interval: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - health_bits: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgAlmanacGlo { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAlmanacGlo(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// GNSS capabilities masks -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GnssCapb { - /// GPS SV active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_active")))] - pub gps_active: u64, - /// GPS L2C active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_l2c")))] - pub gps_l2c: u64, - /// GPS L5 active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "gps_l5")))] - pub gps_l5: u64, - /// GLO active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_active")))] - pub glo_active: u32, - /// GLO L2OF active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_l2of")))] - pub glo_l2of: u32, - /// GLO L3 active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "glo_l3")))] - pub glo_l3: u32, - /// SBAS active mask (PRNs 120..158, AN 7/62.2.2-18/18 Table B-23, - /// ) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sbas_active")))] - pub sbas_active: u64, - /// SBAS L5 active mask (PRNs 120..158, AN 7/62.2.2-18/18 Table B-23, - /// ) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sbas_l5")))] - pub sbas_l5: u64, - /// BDS active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_active")))] - pub bds_active: u64, - /// BDS D2NAV active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_d2nav")))] - pub bds_d2nav: u64, - /// BDS B2 active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_b2")))] - pub bds_b2: u64, - /// BDS B2A active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "bds_b2a")))] - pub bds_b2a: u64, - /// QZSS active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "qzss_active")))] - pub qzss_active: u32, - /// GAL active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "gal_active")))] - pub gal_active: u64, - /// GAL E5 active mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "gal_e5")))] - pub gal_e5: u64, + impl WireFormat for MsgAlmanacGlo { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.lambda_na) + + WireFormat::len(&self.t_lambda_na) + + WireFormat::len(&self.i) + + WireFormat::len(&self.t) + + WireFormat::len(&self.t_dot) + + WireFormat::len(&self.epsilon) + + WireFormat::len(&self.omega) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.lambda_na, buf); + WireFormat::write(&self.t_lambda_na, buf); + WireFormat::write(&self.i, buf); + WireFormat::write(&self.t, buf); + WireFormat::write(&self.t_dot, buf); + WireFormat::write(&self.epsilon, buf); + WireFormat::write(&self.omega, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAlmanacGlo { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + lambda_na: WireFormat::parse_unchecked(buf), + t_lambda_na: WireFormat::parse_unchecked(buf), + i: WireFormat::parse_unchecked(buf), + t: WireFormat::parse_unchecked(buf), + t_dot: WireFormat::parse_unchecked(buf), + epsilon: WireFormat::parse_unchecked(buf), + omega: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for GnssCapb { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.gps_active) - + WireFormat::len(&self.gps_l2c) - + WireFormat::len(&self.gps_l5) - + WireFormat::len(&self.glo_active) - + WireFormat::len(&self.glo_l2of) - + WireFormat::len(&self.glo_l3) - + WireFormat::len(&self.sbas_active) - + WireFormat::len(&self.sbas_l5) - + WireFormat::len(&self.bds_active) - + WireFormat::len(&self.bds_d2nav) - + WireFormat::len(&self.bds_b2) - + WireFormat::len(&self.bds_b2a) - + WireFormat::len(&self.qzss_active) - + WireFormat::len(&self.gal_active) - + WireFormat::len(&self.gal_e5) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.gps_active, buf); - WireFormat::write(&self.gps_l2c, buf); - WireFormat::write(&self.gps_l5, buf); - WireFormat::write(&self.glo_active, buf); - WireFormat::write(&self.glo_l2of, buf); - WireFormat::write(&self.glo_l3, buf); - WireFormat::write(&self.sbas_active, buf); - WireFormat::write(&self.sbas_l5, buf); - WireFormat::write(&self.bds_active, buf); - WireFormat::write(&self.bds_d2nav, buf); - WireFormat::write(&self.bds_b2, buf); - WireFormat::write(&self.bds_b2a, buf); - WireFormat::write(&self.qzss_active, buf); - WireFormat::write(&self.gal_active, buf); - WireFormat::write(&self.gal_e5, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - GnssCapb { - gps_active: WireFormat::parse_unchecked(buf), - gps_l2c: WireFormat::parse_unchecked(buf), - gps_l5: WireFormat::parse_unchecked(buf), - glo_active: WireFormat::parse_unchecked(buf), - glo_l2of: WireFormat::parse_unchecked(buf), - glo_l3: WireFormat::parse_unchecked(buf), - sbas_active: WireFormat::parse_unchecked(buf), - sbas_l5: WireFormat::parse_unchecked(buf), - bds_active: WireFormat::parse_unchecked(buf), - bds_d2nav: WireFormat::parse_unchecked(buf), - bds_b2: WireFormat::parse_unchecked(buf), - bds_b2a: WireFormat::parse_unchecked(buf), - qzss_active: WireFormat::parse_unchecked(buf), - gal_active: WireFormat::parse_unchecked(buf), - gal_e5: WireFormat::parse_unchecked(buf), +pub mod msg_almanac_glo_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The almanac message returns a set of satellite orbit parameters. Almanac + /// data is not very precise and is considered valid for up to several months. + /// Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and + /// almanac" for details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAlmanacGloDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all almanac types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: AlmanacCommonContentDep, + /// Longitude of the first ascending node of the orbit in PZ-90.02 + /// coordinate system + #[cfg_attr(feature = "serde", serde(rename(serialize = "lambda_na")))] + pub lambda_na: f64, + /// Time of the first ascending node passage + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_lambda_na")))] + pub t_lambda_na: f64, + /// Value of inclination at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] + pub i: f64, + /// Value of Draconian period at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: f64, + /// Rate of change of the Draconian period + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_dot")))] + pub t_dot: f64, + /// Eccentricity at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "epsilon")))] + pub epsilon: f64, + /// Argument of perigee at instant of t_lambda + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega")))] + pub omega: f64, + } + + impl ConcreteMessage for MsgAlmanacGloDep { + const MESSAGE_TYPE: u16 = 113; + const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GLO_DEP"; + } + + impl SbpMessage for MsgAlmanacGloDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Satellite broadcast ephemeris for GLO -/// -/// The almanac message returns a set of satellite orbit parameters. Almanac -/// data is not very precise and is considered valid for up to several months. -/// Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and -/// almanac" for details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAlmanacGlo { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all almanac types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: AlmanacCommonContent, - /// Longitude of the first ascending node of the orbit in PZ-90.02 - /// coordinate system - #[cfg_attr(feature = "serde", serde(rename(serialize = "lambda_na")))] - pub lambda_na: f64, - /// Time of the first ascending node passage - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_lambda_na")))] - pub t_lambda_na: f64, - /// Value of inclination at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] - pub i: f64, - /// Value of Draconian period at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: f64, - /// Rate of change of the Draconian period - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_dot")))] - pub t_dot: f64, - /// Eccentricity at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "epsilon")))] - pub epsilon: f64, - /// Argument of perigee at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega")))] - pub omega: f64, -} + impl TryFrom for MsgAlmanacGloDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAlmanacGloDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgAlmanacGlo { - const MESSAGE_TYPE: u16 = 115; - const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GLO"; + impl WireFormat for MsgAlmanacGloDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.lambda_na) + + WireFormat::len(&self.t_lambda_na) + + WireFormat::len(&self.i) + + WireFormat::len(&self.t) + + WireFormat::len(&self.t_dot) + + WireFormat::len(&self.epsilon) + + WireFormat::len(&self.omega) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.lambda_na, buf); + WireFormat::write(&self.t_lambda_na, buf); + WireFormat::write(&self.i, buf); + WireFormat::write(&self.t, buf); + WireFormat::write(&self.t_dot, buf); + WireFormat::write(&self.epsilon, buf); + WireFormat::write(&self.omega, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAlmanacGloDep { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + lambda_na: WireFormat::parse_unchecked(buf), + t_lambda_na: WireFormat::parse_unchecked(buf), + i: WireFormat::parse_unchecked(buf), + t: WireFormat::parse_unchecked(buf), + t_dot: WireFormat::parse_unchecked(buf), + epsilon: WireFormat::parse_unchecked(buf), + omega: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgAlmanacGlo { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_almanac_gps { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GPS + /// + /// The almanac message returns a set of satellite orbit parameters. Almanac + /// data is not very precise and is considered valid for up to several months. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAlmanacGps { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all almanac types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: AlmanacCommonContent, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + } + + impl ConcreteMessage for MsgAlmanacGps { + const MESSAGE_TYPE: u16 = 114; + const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GPS"; + } + + impl SbpMessage for MsgAlmanacGps { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgAlmanacGps { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAlmanacGps(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgAlmanacGlo { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAlmanacGlo(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgAlmanacGps { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAlmanacGps { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgAlmanacGlo { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.lambda_na) - + WireFormat::len(&self.t_lambda_na) - + WireFormat::len(&self.i) - + WireFormat::len(&self.t) - + WireFormat::len(&self.t_dot) - + WireFormat::len(&self.epsilon) - + WireFormat::len(&self.omega) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.lambda_na, buf); - WireFormat::write(&self.t_lambda_na, buf); - WireFormat::write(&self.i, buf); - WireFormat::write(&self.t, buf); - WireFormat::write(&self.t_dot, buf); - WireFormat::write(&self.epsilon, buf); - WireFormat::write(&self.omega, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAlmanacGlo { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - lambda_na: WireFormat::parse_unchecked(buf), - t_lambda_na: WireFormat::parse_unchecked(buf), - i: WireFormat::parse_unchecked(buf), - t: WireFormat::parse_unchecked(buf), - t_dot: WireFormat::parse_unchecked(buf), - epsilon: WireFormat::parse_unchecked(buf), - omega: WireFormat::parse_unchecked(buf), +pub mod msg_almanac_gps_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GPS + /// + /// The almanac message returns a set of satellite orbit parameters. Almanac + /// data is not very precise and is considered valid for up to several months. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAlmanacGpsDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all almanac types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: AlmanacCommonContentDep, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + } + + impl ConcreteMessage for MsgAlmanacGpsDep { + const MESSAGE_TYPE: u16 = 112; + const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GPS_DEP"; + } + + impl SbpMessage for MsgAlmanacGpsDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Satellite broadcast ephemeris for GLO -/// -/// The almanac message returns a set of satellite orbit parameters. Almanac -/// data is not very precise and is considered valid for up to several months. -/// Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and -/// almanac" for details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAlmanacGloDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all almanac types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: AlmanacCommonContentDep, - /// Longitude of the first ascending node of the orbit in PZ-90.02 - /// coordinate system - #[cfg_attr(feature = "serde", serde(rename(serialize = "lambda_na")))] - pub lambda_na: f64, - /// Time of the first ascending node passage - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_lambda_na")))] - pub t_lambda_na: f64, - /// Value of inclination at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "i")))] - pub i: f64, - /// Value of Draconian period at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: f64, - /// Rate of change of the Draconian period - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_dot")))] - pub t_dot: f64, - /// Eccentricity at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "epsilon")))] - pub epsilon: f64, - /// Argument of perigee at instant of t_lambda - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega")))] - pub omega: f64, -} + impl TryFrom for MsgAlmanacGpsDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAlmanacGpsDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgAlmanacGloDep { - const MESSAGE_TYPE: u16 = 113; - const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GLO_DEP"; + impl WireFormat for MsgAlmanacGpsDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAlmanacGpsDep { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgAlmanacGloDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_base_pos_ecef { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Base station position in ECEF + /// + /// The base station position message is the position reported by the base + /// station itself in absolute Earth Centered Earth Fixed coordinates. It is + /// used for pseudo-absolute RTK positioning, and is required to be a high- + /// accuracy surveyed location of the base station. Any error here will result + /// in an error in the pseudo-absolute position output. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBasePosEcef { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// ECEF X coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: f64, + /// ECEF Y coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: f64, + /// ECEF Z coordinate + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: f64, + } + + impl ConcreteMessage for MsgBasePosEcef { + const MESSAGE_TYPE: u16 = 72; + const MESSAGE_NAME: &'static str = "MSG_BASE_POS_ECEF"; + } + + impl SbpMessage for MsgBasePosEcef { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgBasePosEcef { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBasePosEcef(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgAlmanacGloDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAlmanacGloDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgBasePosEcef { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.x) + WireFormat::len(&self.y) + WireFormat::len(&self.z) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBasePosEcef { + sender_id: None, + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgAlmanacGloDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.lambda_na) - + WireFormat::len(&self.t_lambda_na) - + WireFormat::len(&self.i) - + WireFormat::len(&self.t) - + WireFormat::len(&self.t_dot) - + WireFormat::len(&self.epsilon) - + WireFormat::len(&self.omega) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.lambda_na, buf); - WireFormat::write(&self.t_lambda_na, buf); - WireFormat::write(&self.i, buf); - WireFormat::write(&self.t, buf); - WireFormat::write(&self.t_dot, buf); - WireFormat::write(&self.epsilon, buf); - WireFormat::write(&self.omega, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAlmanacGloDep { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - lambda_na: WireFormat::parse_unchecked(buf), - t_lambda_na: WireFormat::parse_unchecked(buf), - i: WireFormat::parse_unchecked(buf), - t: WireFormat::parse_unchecked(buf), - t_dot: WireFormat::parse_unchecked(buf), - epsilon: WireFormat::parse_unchecked(buf), - omega: WireFormat::parse_unchecked(buf), +pub mod msg_base_pos_llh { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Base station position + /// + /// The base station position message is the position reported by the base + /// station itself. It is used for pseudo-absolute RTK positioning, and is + /// required to be a high-accuracy surveyed location of the base station. Any + /// error here will result in an error in the pseudo-absolute position output. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBasePosLlh { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] + pub lat: f64, + /// Longitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] + pub lon: f64, + /// Height + #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] + pub height: f64, + } + + impl ConcreteMessage for MsgBasePosLlh { + const MESSAGE_TYPE: u16 = 68; + const MESSAGE_NAME: &'static str = "MSG_BASE_POS_LLH"; + } + + impl SbpMessage for MsgBasePosLlh { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Satellite broadcast ephemeris for GPS -/// -/// The almanac message returns a set of satellite orbit parameters. Almanac -/// data is not very precise and is considered valid for up to several months. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAlmanacGps { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all almanac types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: AlmanacCommonContent, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, -} + impl TryFrom for MsgBasePosLlh { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBasePosLlh(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgAlmanacGps { - const MESSAGE_TYPE: u16 = 114; - const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GPS"; + impl WireFormat for MsgBasePosLlh { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.lat) + WireFormat::len(&self.lon) + WireFormat::len(&self.height) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.lat, buf); + WireFormat::write(&self.lon, buf); + WireFormat::write(&self.height, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBasePosLlh { + sender_id: None, + lat: WireFormat::parse_unchecked(buf), + lon: WireFormat::parse_unchecked(buf), + height: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgAlmanacGps { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_bds { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for BDS + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate BDS satellite position, velocity, and clock offset. + /// Please see the BeiDou Navigation Satellite System SIS-ICD Version 2.1, + /// Table 5-9 for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisBds { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// Group delay differential for B1 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd1")))] + pub tgd1: f32, + /// Group delay differential for B2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd2")))] + pub tgd2: f32, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f32, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f32, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f32, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f32, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f32, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f32, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f32, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f32, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of ephemeris data + /// Calculated from the navigation data parameter t_oe per RTCM/CSNO + /// recommendation: IODE = mod (t_oe / 720, 240) + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + /// Calculated from the navigation data parameter t_oe per RTCM/CSNO + /// recommendation: IODE = mod (t_oc / 720, 240) + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisBds { + const MESSAGE_TYPE: u16 = 137; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_BDS"; + } + + impl SbpMessage for MsgEphemerisBds { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisBds { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisBds(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgAlmanacGps { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAlmanacGps(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisBds { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.tgd1) + + WireFormat::len(&self.tgd2) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.tgd1, buf); + WireFormat::write(&self.tgd2, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisBds { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + tgd1: WireFormat::parse_unchecked(buf), + tgd2: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgAlmanacGps { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAlmanacGps { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] + pub toe_tow: f64, + /// Week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] + pub toe_wn: u16, + /// Clock reference time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] + pub toc_tow: f64, + /// Clock reference week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] + pub toc_wn: u16, + /// Is valid? + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite is healthy? + #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] + pub healthy: u8, + /// PRN being tracked + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + } + + impl ConcreteMessage for MsgEphemerisDepA { + const MESSAGE_TYPE: u16 = 26; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_A"; + } + + impl SbpMessage for MsgEphemerisDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Satellite broadcast ephemeris for GPS -/// -/// The almanac message returns a set of satellite orbit parameters. Almanac -/// data is not very precise and is considered valid for up to several months. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAlmanacGpsDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all almanac types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: AlmanacCommonContentDep, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, -} + impl TryFrom for MsgEphemerisDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgAlmanacGpsDep { - const MESSAGE_TYPE: u16 = 112; - const MESSAGE_NAME: &'static str = "MSG_ALMANAC_GPS_DEP"; + impl WireFormat for MsgEphemerisDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toe_tow) + + WireFormat::len(&self.toe_wn) + + WireFormat::len(&self.toc_tow) + + WireFormat::len(&self.toc_wn) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.healthy) + + WireFormat::len(&self.prn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toe_tow, buf); + WireFormat::write(&self.toe_wn, buf); + WireFormat::write(&self.toc_tow, buf); + WireFormat::write(&self.toc_wn, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.healthy, buf); + WireFormat::write(&self.prn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisDepA { + sender_id: None, + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toe_tow: WireFormat::parse_unchecked(buf), + toe_wn: WireFormat::parse_unchecked(buf), + toc_tow: WireFormat::parse_unchecked(buf), + toc_wn: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + healthy: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgAlmanacGpsDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] + pub toe_tow: f64, + /// Week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] + pub toe_wn: u16, + /// Clock reference time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] + pub toc_tow: f64, + /// Clock reference week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] + pub toc_wn: u16, + /// Is valid? + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite is healthy? + #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] + pub healthy: u8, + /// PRN being tracked + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + } + + impl ConcreteMessage for MsgEphemerisDepB { + const MESSAGE_TYPE: u16 = 70; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_B"; + } + + impl SbpMessage for MsgEphemerisDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgAlmanacGpsDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAlmanacGpsDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toe_tow) + + WireFormat::len(&self.toe_wn) + + WireFormat::len(&self.toc_tow) + + WireFormat::len(&self.toc_wn) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.healthy) + + WireFormat::len(&self.prn) + + WireFormat::len(&self.iode) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toe_tow, buf); + WireFormat::write(&self.toe_wn, buf); + WireFormat::write(&self.toc_tow, buf); + WireFormat::write(&self.toc_wn, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.healthy, buf); + WireFormat::write(&self.prn, buf); + WireFormat::write(&self.iode, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisDepB { + sender_id: None, + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toe_tow: WireFormat::parse_unchecked(buf), + toe_wn: WireFormat::parse_unchecked(buf), + toc_tow: WireFormat::parse_unchecked(buf), + toc_wn: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + healthy: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgAlmanacGpsDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAlmanacGpsDep { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_dep_c { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GPS satellite position, velocity, and clock offset. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Table 20-III) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisDepC { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] + pub toe_tow: f64, + /// Week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] + pub toe_wn: u16, + /// Clock reference time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] + pub toc_tow: f64, + /// Clock reference week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] + pub toc_wn: u16, + /// Is valid? + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite is healthy? + #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] + pub healthy: u8, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + /// Reserved field + #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] + pub reserved: u32, + } + + impl ConcreteMessage for MsgEphemerisDepC { + const MESSAGE_TYPE: u16 = 71; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_C"; + } + + impl SbpMessage for MsgEphemerisDepC { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Base station position in ECEF -/// -/// The base station position message is the position reported by the base -/// station itself in absolute Earth Centered Earth Fixed coordinates. It is -/// used for pseudo-absolute RTK positioning, and is required to be a high- -/// accuracy surveyed location of the base station. Any error here will result -/// in an error in the pseudo-absolute position output. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBasePosEcef { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// ECEF X coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: f64, - /// ECEF Y coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: f64, - /// ECEF Z coordinate - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: f64, -} + impl TryFrom for MsgEphemerisDepC { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisDepC(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgBasePosEcef { - const MESSAGE_TYPE: u16 = 72; - const MESSAGE_NAME: &'static str = "MSG_BASE_POS_ECEF"; + impl WireFormat for MsgEphemerisDepC { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toe_tow) + + WireFormat::len(&self.toe_wn) + + WireFormat::len(&self.toc_tow) + + WireFormat::len(&self.toc_wn) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.healthy) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + + WireFormat::len(&self.reserved) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toe_tow, buf); + WireFormat::write(&self.toe_wn, buf); + WireFormat::write(&self.toc_tow, buf); + WireFormat::write(&self.toc_wn, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.healthy, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + WireFormat::write(&self.reserved, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisDepC { + sender_id: None, + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toe_tow: WireFormat::parse_unchecked(buf), + toe_wn: WireFormat::parse_unchecked(buf), + toc_tow: WireFormat::parse_unchecked(buf), + toc_wn: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + healthy: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + reserved: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgBasePosEcef { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_dep_d { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GPS satellite position, velocity, and clock offset. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Table 20-III) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisDepD { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] + pub toe_tow: f64, + /// Week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] + pub toe_wn: u16, + /// Clock reference time of week + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] + pub toc_tow: f64, + /// Clock reference week number + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] + pub toc_wn: u16, + /// Is valid? + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + /// Satellite is healthy? + #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] + pub healthy: u8, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + /// Reserved field + #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] + pub reserved: u32, + } + + impl ConcreteMessage for MsgEphemerisDepD { + const MESSAGE_TYPE: u16 = 128; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_D"; + } + + impl SbpMessage for MsgEphemerisDepD { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisDepD { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisDepD(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgBasePosEcef { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBasePosEcef(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisDepD { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toe_tow) + + WireFormat::len(&self.toe_wn) + + WireFormat::len(&self.toc_tow) + + WireFormat::len(&self.toc_wn) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.healthy) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + + WireFormat::len(&self.reserved) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toe_tow, buf); + WireFormat::write(&self.toe_wn, buf); + WireFormat::write(&self.toc_tow, buf); + WireFormat::write(&self.toc_wn, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.healthy, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + WireFormat::write(&self.reserved, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisDepD { + sender_id: None, + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toe_tow: WireFormat::parse_unchecked(buf), + toe_wn: WireFormat::parse_unchecked(buf), + toc_tow: WireFormat::parse_unchecked(buf), + toc_wn: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + healthy: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + reserved: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgBasePosEcef { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.x) + WireFormat::len(&self.y) + WireFormat::len(&self.z) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBasePosEcef { - sender_id: None, - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_gal { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for Galileo + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate Galileo satellite position, velocity, and clock offset. + /// Please see the Signal In Space ICD OS SIS ICD, Issue 1.3, December 2016 + /// for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGal { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// E1-E5a Broadcast Group Delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5a")))] + pub bgd_e1e5a: f32, + /// E1-E5b Broadcast Group Delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5b")))] + pub bgd_e1e5b: f32, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f32, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f32, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f32, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f32, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f32, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f32, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f32, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of data (IODnav) + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u16, + /// Issue of data (IODnav). Always equal to iode + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + /// 0=I/NAV, 1=F/NAV + #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] + pub source: u8, + } + + impl ConcreteMessage for MsgEphemerisGal { + const MESSAGE_TYPE: u16 = 141; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GAL"; + } + + impl SbpMessage for MsgEphemerisGal { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Base station position -/// -/// The base station position message is the position reported by the base -/// station itself. It is used for pseudo-absolute RTK positioning, and is -/// required to be a high-accuracy surveyed location of the base station. Any -/// error here will result in an error in the pseudo-absolute position output. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBasePosLlh { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat")))] - pub lat: f64, - /// Longitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon")))] - pub lon: f64, - /// Height - #[cfg_attr(feature = "serde", serde(rename(serialize = "height")))] - pub height: f64, -} + impl TryFrom for MsgEphemerisGal { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGal(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgBasePosLlh { - const MESSAGE_TYPE: u16 = 68; - const MESSAGE_NAME: &'static str = "MSG_BASE_POS_LLH"; + impl WireFormat for MsgEphemerisGal { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.bgd_e1e5a) + + WireFormat::len(&self.bgd_e1e5b) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + + WireFormat::len(&self.source) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.bgd_e1e5a, buf); + WireFormat::write(&self.bgd_e1e5b, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + WireFormat::write(&self.source, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGal { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + bgd_e1e5a: WireFormat::parse_unchecked(buf), + bgd_e1e5b: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + source: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgBasePosLlh { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_gal_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// This observation message has been deprecated in favor of an ephemeris + /// message with explicit source of NAV data. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGalDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// E1-E5a Broadcast Group Delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5a")))] + pub bgd_e1e5a: f32, + /// E1-E5b Broadcast Group Delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5b")))] + pub bgd_e1e5b: f32, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f32, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f32, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f32, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f32, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f32, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f32, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f32, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of data (IODnav) + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u16, + /// Issue of data (IODnav). Always equal to iode + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisGalDepA { + const MESSAGE_TYPE: u16 = 149; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GAL_DEP_A"; + } + + impl SbpMessage for MsgEphemerisGalDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisGalDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGalDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgBasePosLlh { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBasePosLlh(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisGalDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.bgd_e1e5a) + + WireFormat::len(&self.bgd_e1e5b) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.bgd_e1e5a, buf); + WireFormat::write(&self.bgd_e1e5b, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGalDepA { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + bgd_e1e5a: WireFormat::parse_unchecked(buf), + bgd_e1e5b: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgBasePosLlh { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.lat) + WireFormat::len(&self.lon) + WireFormat::len(&self.height) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.lat, buf); - WireFormat::write(&self.lon, buf); - WireFormat::write(&self.height, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBasePosLlh { - sender_id: None, - lat: WireFormat::parse_unchecked(buf), - lon: WireFormat::parse_unchecked(buf), - height: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_glo { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GLO satellite position, velocity, and clock offset. + /// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of + /// immediate information (ephemeris parameters)" for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGlo { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// Relative deviation of predicted carrier frequency from nominal + #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] + pub gamma: f32, + /// Correction to the SV time + #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] + pub tau: f32, + /// Equipment delay between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] + pub d_tau: f32, + /// Position of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity vector of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f32; 3], + /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] + pub fcn: u8, + /// Issue of data. Equal to the 7 bits of the immediate data word t_b + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] + pub iod: u8, + } + + impl ConcreteMessage for MsgEphemerisGlo { + const MESSAGE_TYPE: u16 = 139; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO"; + } + + impl SbpMessage for MsgEphemerisGlo { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Satellite broadcast ephemeris for BDS -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate BDS satellite position, velocity, and clock offset. -/// Please see the BeiDou Navigation Satellite System SIS-ICD Version 2.1, -/// Table 5-9 for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisBds { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// Group delay differential for B1 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd1")))] - pub tgd1: f32, - /// Group delay differential for B2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd2")))] - pub tgd2: f32, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f32, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f32, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f32, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f32, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f32, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f32, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f32, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f32, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of ephemeris data - /// Calculated from the navigation data parameter t_oe per RTCM/CSNO - /// recommendation: IODE = mod (t_oe / 720, 240) - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - /// Calculated from the navigation data parameter t_oe per RTCM/CSNO - /// recommendation: IODE = mod (t_oc / 720, 240) - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} + impl TryFrom for MsgEphemerisGlo { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGlo(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgEphemerisBds { - const MESSAGE_TYPE: u16 = 137; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_BDS"; + impl WireFormat for MsgEphemerisGlo { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f32; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.gamma) + + WireFormat::len(&self.tau) + + WireFormat::len(&self.d_tau) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.fcn) + + WireFormat::len(&self.iod) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.gamma, buf); + WireFormat::write(&self.tau, buf); + WireFormat::write(&self.d_tau, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.fcn, buf); + WireFormat::write(&self.iod, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGlo { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + gamma: WireFormat::parse_unchecked(buf), + tau: WireFormat::parse_unchecked(buf), + d_tau: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + fcn: WireFormat::parse_unchecked(buf), + iod: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgEphemerisBds { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_glo_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GLO satellite position, velocity, and clock offset. + /// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of + /// immediate information (ephemeris parameters)" for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGloDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepA, + /// Relative deviation of predicted carrier frequency from nominal + #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] + pub gamma: f64, + /// Correction to the SV time + #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] + pub tau: f64, + /// Position of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity vector of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + } + + impl ConcreteMessage for MsgEphemerisGloDepA { + const MESSAGE_TYPE: u16 = 131; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_A"; + } + + impl SbpMessage for MsgEphemerisGloDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisGloDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGloDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgEphemerisBds { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisBds(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisGloDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.gamma) + + WireFormat::len(&self.tau) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.gamma, buf); + WireFormat::write(&self.tau, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGloDepA { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + gamma: WireFormat::parse_unchecked(buf), + tau: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgEphemerisBds { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.tgd1) - + WireFormat::len(&self.tgd2) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.tgd1, buf); - WireFormat::write(&self.tgd2, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisBds { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - tgd1: WireFormat::parse_unchecked(buf), - tgd2: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_glo_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GLO satellite position, velocity, and clock offset. + /// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of + /// immediate information (ephemeris parameters)" for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGloDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepB, + /// Relative deviation of predicted carrier frequency from nominal + #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] + pub gamma: f64, + /// Correction to the SV time + #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] + pub tau: f64, + /// Position of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity vector of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + } + + impl ConcreteMessage for MsgEphemerisGloDepB { + const MESSAGE_TYPE: u16 = 133; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_B"; + } + + impl SbpMessage for MsgEphemerisGloDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] - pub toe_tow: f64, - /// Week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] - pub toe_wn: u16, - /// Clock reference time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] - pub toc_tow: f64, - /// Clock reference week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] - pub toc_wn: u16, - /// Is valid? - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite is healthy? - #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] - pub healthy: u8, - /// PRN being tracked - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, -} + impl TryFrom for MsgEphemerisGloDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGloDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgEphemerisDepA { - const MESSAGE_TYPE: u16 = 26; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_A"; + impl WireFormat for MsgEphemerisGloDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.gamma) + + WireFormat::len(&self.tau) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.gamma, buf); + WireFormat::write(&self.tau, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGloDepB { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + gamma: WireFormat::parse_unchecked(buf), + tau: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgEphemerisDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +pub mod msg_ephemeris_glo_dep_c { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GLO + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GLO satellite position, velocity, and clock offset. + /// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of + /// immediate information (ephemeris parameters)" for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGloDepC { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepB, + /// Relative deviation of predicted carrier frequency from nominal + #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] + pub gamma: f64, + /// Correction to the SV time + #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] + pub tau: f64, + /// Equipment delay between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] + pub d_tau: f64, + /// Position of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity vector of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] + pub fcn: u8, + } + + impl ConcreteMessage for MsgEphemerisGloDepC { + const MESSAGE_TYPE: u16 = 135; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_C"; + } + + impl SbpMessage for MsgEphemerisGloDepC { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgEphemerisGloDepC { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGloDepC(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgEphemerisDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgEphemerisGloDepC { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.gamma) + + WireFormat::len(&self.tau) + + WireFormat::len(&self.d_tau) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.fcn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.gamma, buf); + WireFormat::write(&self.tau, buf); + WireFormat::write(&self.d_tau, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.fcn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGloDepC { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + gamma: WireFormat::parse_unchecked(buf), + tau: WireFormat::parse_unchecked(buf), + d_tau: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + fcn: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgEphemerisDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toe_tow) - + WireFormat::len(&self.toe_wn) - + WireFormat::len(&self.toc_tow) - + WireFormat::len(&self.toc_wn) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.healthy) - + WireFormat::len(&self.prn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toe_tow, buf); - WireFormat::write(&self.toe_wn, buf); - WireFormat::write(&self.toc_tow, buf); - WireFormat::write(&self.toc_wn, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.healthy, buf); - WireFormat::write(&self.prn, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisDepA { - sender_id: None, - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toe_tow: WireFormat::parse_unchecked(buf), - toe_wn: WireFormat::parse_unchecked(buf), - toc_tow: WireFormat::parse_unchecked(buf), - toc_wn: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - healthy: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), +pub mod msg_ephemeris_glo_dep_d { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// This observation message has been deprecated in favor of ephemeris message + /// using floats for size reduction. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGloDepD { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepB, + /// Relative deviation of predicted carrier frequency from nominal + #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] + pub gamma: f64, + /// Correction to the SV time + #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] + pub tau: f64, + /// Equipment delay between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] + pub d_tau: f64, + /// Position of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity vector of the SV at tb in PZ-90.02 coordinates system + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid + #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] + pub fcn: u8, + /// Issue of data. Equal to the 7 bits of the immediate data word t_b + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] + pub iod: u8, + } + + impl ConcreteMessage for MsgEphemerisGloDepD { + const MESSAGE_TYPE: u16 = 136; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_D"; + } + + impl SbpMessage for MsgEphemerisGloDepD { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] - pub toe_tow: f64, - /// Week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] - pub toe_wn: u16, - /// Clock reference time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] - pub toc_tow: f64, - /// Clock reference week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] - pub toc_wn: u16, - /// Is valid? - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite is healthy? - #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] - pub healthy: u8, - /// PRN being tracked - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, -} + impl TryFrom for MsgEphemerisGloDepD { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGloDepD(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgEphemerisDepB { - const MESSAGE_TYPE: u16 = 70; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_B"; + impl WireFormat for MsgEphemerisGloDepD { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.gamma) + + WireFormat::len(&self.tau) + + WireFormat::len(&self.d_tau) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.fcn) + + WireFormat::len(&self.iod) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.gamma, buf); + WireFormat::write(&self.tau, buf); + WireFormat::write(&self.d_tau, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.fcn, buf); + WireFormat::write(&self.iod, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGloDepD { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + gamma: WireFormat::parse_unchecked(buf), + tau: WireFormat::parse_unchecked(buf), + d_tau: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + fcn: WireFormat::parse_unchecked(buf), + iod: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgEphemerisDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id +pub mod msg_ephemeris_gps { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GPS + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GPS satellite position, velocity, and clock offset. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Table 20-III) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGps { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f32, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f32, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f32, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f32, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f32, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f32, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f32, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f32, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f32, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f32, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisGps { + const MESSAGE_TYPE: u16 = 138; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS"; + } + + impl SbpMessage for MsgEphemerisGps { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgEphemerisGps { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGps(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgEphemerisGps { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGps { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisDepB(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_gps_dep_e { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for GPS + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate GPS satellite position, velocity, and clock offset. + /// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- + /// GPS-200, Table 20-III) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGpsDepE { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepA, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeDep, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisGpsDepE { + const MESSAGE_TYPE: u16 = 129; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS_DEP_E"; + } + + impl SbpMessage for MsgEphemerisGpsDepE { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toe_tow) - + WireFormat::len(&self.toe_wn) - + WireFormat::len(&self.toc_tow) - + WireFormat::len(&self.toc_wn) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.healthy) - + WireFormat::len(&self.prn) - + WireFormat::len(&self.iode) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toe_tow, buf); - WireFormat::write(&self.toe_wn, buf); - WireFormat::write(&self.toc_tow, buf); - WireFormat::write(&self.toc_wn, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.healthy, buf); - WireFormat::write(&self.prn, buf); - WireFormat::write(&self.iode, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisDepB { - sender_id: None, - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toe_tow: WireFormat::parse_unchecked(buf), - toe_wn: WireFormat::parse_unchecked(buf), - toc_tow: WireFormat::parse_unchecked(buf), - toc_wn: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - healthy: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisGpsDepE { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGpsDepE(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GPS satellite position, velocity, and clock offset. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Table 20-III) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisDepC { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] - pub toe_tow: f64, - /// Week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] - pub toe_wn: u16, - /// Clock reference time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] - pub toc_tow: f64, - /// Clock reference week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] - pub toc_wn: u16, - /// Is valid? - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite is healthy? - #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] - pub healthy: u8, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, - /// Reserved field - #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] - pub reserved: u32, -} -impl ConcreteMessage for MsgEphemerisDepC { - const MESSAGE_TYPE: u16 = 71; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_C"; -} - -impl SbpMessage for MsgEphemerisDepC { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisGpsDepE { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGpsDepE { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisDepC { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisDepC(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_gps_dep_f { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// This observation message has been deprecated in favor of ephemeris message + /// using floats for size reduction. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisGpsDepF { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepB, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f64, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f64, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f64, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f64, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f64, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f64, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f64, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f64, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f64, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f64, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisGpsDepF { + const MESSAGE_TYPE: u16 = 134; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS_DEP_F"; + } + + impl SbpMessage for MsgEphemerisGpsDepF { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisDepC { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toe_tow) - + WireFormat::len(&self.toe_wn) - + WireFormat::len(&self.toc_tow) - + WireFormat::len(&self.toc_wn) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.healthy) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - + WireFormat::len(&self.reserved) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toe_tow, buf); - WireFormat::write(&self.toe_wn, buf); - WireFormat::write(&self.toc_tow, buf); - WireFormat::write(&self.toc_wn, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.healthy, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - WireFormat::write(&self.reserved, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisDepC { - sender_id: None, - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toe_tow: WireFormat::parse_unchecked(buf), - toe_wn: WireFormat::parse_unchecked(buf), - toc_tow: WireFormat::parse_unchecked(buf), - toc_wn: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - healthy: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), - reserved: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisGpsDepF { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisGpsDepF(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GPS satellite position, velocity, and clock offset. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Table 20-III) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisDepD { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_tow")))] - pub toe_tow: f64, - /// Week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toe_wn")))] - pub toe_wn: u16, - /// Clock reference time of week - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_tow")))] - pub toc_tow: f64, - /// Clock reference week number - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc_wn")))] - pub toc_wn: u16, - /// Is valid? - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - /// Satellite is healthy? - #[cfg_attr(feature = "serde", serde(rename(serialize = "healthy")))] - pub healthy: u8, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, - /// Reserved field - #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] - pub reserved: u32, -} - -impl ConcreteMessage for MsgEphemerisDepD { - const MESSAGE_TYPE: u16 = 128; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_DEP_D"; -} -impl SbpMessage for MsgEphemerisDepD { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisGpsDepF { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisGpsDepF { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisDepD { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisDepD(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_qzss { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite broadcast ephemeris for QZSS + /// + /// The ephemeris message returns a set of satellite orbit parameters that is + /// used to calculate QZSS satellite position, velocity, and clock offset. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisQzss { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// Group delay differential between L1 and L2 + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: f32, + /// Amplitude of the sine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] + pub c_rs: f32, + /// Amplitude of the cosine harmonic correction term to the orbit radius + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] + pub c_rc: f32, + /// Amplitude of the cosine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] + pub c_uc: f32, + /// Amplitude of the sine harmonic correction term to the argument of + /// latitude + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] + pub c_us: f32, + /// Amplitude of the cosine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] + pub c_ic: f32, + /// Amplitude of the sine harmonic correction term to the angle of + /// inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] + pub c_is: f32, + /// Mean motion difference + #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] + pub dn: f64, + /// Mean anomaly at reference time + #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] + pub m0: f64, + /// Eccentricity of satellite orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] + pub ecc: f64, + /// Square root of the semi-major axis of orbit + #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] + pub sqrta: f64, + /// Longitude of ascending node of orbit plane at weekly epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] + pub omega0: f64, + /// Rate of right ascension + #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] + pub omegadot: f64, + /// Argument of perigee + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: f64, + /// Inclination + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] + pub inc: f64, + /// Inclination first derivative + #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] + pub inc_dot: f64, + /// Polynomial clock correction coefficient (clock bias) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] + pub af0: f32, + /// Polynomial clock correction coefficient (clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] + pub af1: f32, + /// Polynomial clock correction coefficient (rate of clock drift) + #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] + pub af2: f32, + /// Clock reference + #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] + pub toc: GpsTimeSec, + /// Issue of ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] + pub iode: u8, + /// Issue of clock data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] + pub iodc: u16, + } + + impl ConcreteMessage for MsgEphemerisQzss { + const MESSAGE_TYPE: u16 = 142; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_QZSS"; + } + + impl SbpMessage for MsgEphemerisQzss { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisDepD { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toe_tow) - + WireFormat::len(&self.toe_wn) - + WireFormat::len(&self.toc_tow) - + WireFormat::len(&self.toc_wn) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.healthy) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - + WireFormat::len(&self.reserved) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toe_tow, buf); - WireFormat::write(&self.toe_wn, buf); - WireFormat::write(&self.toc_tow, buf); - WireFormat::write(&self.toc_wn, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.healthy, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - WireFormat::write(&self.reserved, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisDepD { - sender_id: None, - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toe_tow: WireFormat::parse_unchecked(buf), - toe_wn: WireFormat::parse_unchecked(buf), - toc_tow: WireFormat::parse_unchecked(buf), - toc_wn: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - healthy: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), - reserved: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisQzss { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisQzss(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Satellite broadcast ephemeris for Galileo -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate Galileo satellite position, velocity, and clock offset. -/// Please see the Signal In Space ICD OS SIS ICD, Issue 1.3, December 2016 -/// for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGal { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// E1-E5a Broadcast Group Delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5a")))] - pub bgd_e1e5a: f32, - /// E1-E5b Broadcast Group Delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5b")))] - pub bgd_e1e5b: f32, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f32, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f32, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f32, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f32, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f32, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f32, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f32, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of data (IODnav) - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u16, - /// Issue of data (IODnav). Always equal to iode - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, - /// 0=I/NAV, 1=F/NAV - #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] - pub source: u8, -} - -impl ConcreteMessage for MsgEphemerisGal { - const MESSAGE_TYPE: u16 = 141; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GAL"; -} - -impl SbpMessage for MsgEphemerisGal { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisQzss { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.c_rs) + + WireFormat::len(&self.c_rc) + + WireFormat::len(&self.c_uc) + + WireFormat::len(&self.c_us) + + WireFormat::len(&self.c_ic) + + WireFormat::len(&self.c_is) + + WireFormat::len(&self.dn) + + WireFormat::len(&self.m0) + + WireFormat::len(&self.ecc) + + WireFormat::len(&self.sqrta) + + WireFormat::len(&self.omega0) + + WireFormat::len(&self.omegadot) + + WireFormat::len(&self.w) + + WireFormat::len(&self.inc) + + WireFormat::len(&self.inc_dot) + + WireFormat::len(&self.af0) + + WireFormat::len(&self.af1) + + WireFormat::len(&self.af2) + + WireFormat::len(&self.toc) + + WireFormat::len(&self.iode) + + WireFormat::len(&self.iodc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.c_rs, buf); + WireFormat::write(&self.c_rc, buf); + WireFormat::write(&self.c_uc, buf); + WireFormat::write(&self.c_us, buf); + WireFormat::write(&self.c_ic, buf); + WireFormat::write(&self.c_is, buf); + WireFormat::write(&self.dn, buf); + WireFormat::write(&self.m0, buf); + WireFormat::write(&self.ecc, buf); + WireFormat::write(&self.sqrta, buf); + WireFormat::write(&self.omega0, buf); + WireFormat::write(&self.omegadot, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.inc, buf); + WireFormat::write(&self.inc_dot, buf); + WireFormat::write(&self.af0, buf); + WireFormat::write(&self.af1, buf); + WireFormat::write(&self.af2, buf); + WireFormat::write(&self.toc, buf); + WireFormat::write(&self.iode, buf); + WireFormat::write(&self.iodc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisQzss { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + c_rs: WireFormat::parse_unchecked(buf), + c_rc: WireFormat::parse_unchecked(buf), + c_uc: WireFormat::parse_unchecked(buf), + c_us: WireFormat::parse_unchecked(buf), + c_ic: WireFormat::parse_unchecked(buf), + c_is: WireFormat::parse_unchecked(buf), + dn: WireFormat::parse_unchecked(buf), + m0: WireFormat::parse_unchecked(buf), + ecc: WireFormat::parse_unchecked(buf), + sqrta: WireFormat::parse_unchecked(buf), + omega0: WireFormat::parse_unchecked(buf), + omegadot: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + inc: WireFormat::parse_unchecked(buf), + inc_dot: WireFormat::parse_unchecked(buf), + af0: WireFormat::parse_unchecked(buf), + af1: WireFormat::parse_unchecked(buf), + af2: WireFormat::parse_unchecked(buf), + toc: WireFormat::parse_unchecked(buf), + iode: WireFormat::parse_unchecked(buf), + iodc: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGal { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGal(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_sbas { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Satellite broadcast ephemeris for SBAS + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisSbas { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContent, + /// Position of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f32; 3], + /// Acceleration of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f32; 3], + /// Time offset of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] + pub a_gf0: f32, + /// Drift of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] + pub a_gf1: f32, + } + + impl ConcreteMessage for MsgEphemerisSbas { + const MESSAGE_TYPE: u16 = 140; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS"; + } + + impl SbpMessage for MsgEphemerisSbas { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGal { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.bgd_e1e5a) - + WireFormat::len(&self.bgd_e1e5b) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - + WireFormat::len(&self.source) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.bgd_e1e5a, buf); - WireFormat::write(&self.bgd_e1e5b, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - WireFormat::write(&self.source, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGal { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - bgd_e1e5a: WireFormat::parse_unchecked(buf), - bgd_e1e5b: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), - source: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisSbas { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisSbas(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Deprecated -/// -/// This observation message has been deprecated in favor of an ephemeris -/// message with explicit source of NAV data. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGalDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// E1-E5a Broadcast Group Delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5a")))] - pub bgd_e1e5a: f32, - /// E1-E5b Broadcast Group Delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "bgd_e1e5b")))] - pub bgd_e1e5b: f32, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f32, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f32, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f32, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f32, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f32, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f32, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f32, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of data (IODnav) - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u16, - /// Issue of data (IODnav). Always equal to iode - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} - -impl ConcreteMessage for MsgEphemerisGalDepA { - const MESSAGE_TYPE: u16 = 149; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GAL_DEP_A"; -} -impl SbpMessage for MsgEphemerisGalDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisSbas { + const MIN_LEN: usize = ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f32; 3] as WireFormat>::MIN_LEN + + <[f32; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.a_gf0) + + WireFormat::len(&self.a_gf1) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.a_gf0, buf); + WireFormat::write(&self.a_gf1, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisSbas { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + a_gf0: WireFormat::parse_unchecked(buf), + a_gf1: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGalDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGalDepA(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_sbas_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Satellite broadcast ephemeris for SBAS + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisSbasDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepA, + /// Position of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + /// Time offset of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] + pub a_gf0: f64, + /// Drift of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] + pub a_gf1: f64, + } + + impl ConcreteMessage for MsgEphemerisSbasDepA { + const MESSAGE_TYPE: u16 = 130; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS_DEP_A"; + } + + impl SbpMessage for MsgEphemerisSbasDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGalDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.bgd_e1e5a) - + WireFormat::len(&self.bgd_e1e5b) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.bgd_e1e5a, buf); - WireFormat::write(&self.bgd_e1e5b, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGalDepA { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - bgd_e1e5a: WireFormat::parse_unchecked(buf), - bgd_e1e5b: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisSbasDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisSbasDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for GLO -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GLO satellite position, velocity, and clock offset. -/// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of -/// immediate information (ephemeris parameters)" for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGlo { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// Relative deviation of predicted carrier frequency from nominal - #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] - pub gamma: f32, - /// Correction to the SV time - #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] - pub tau: f32, - /// Equipment delay between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] - pub d_tau: f32, - /// Position of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity vector of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f32; 3], - /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] - pub fcn: u8, - /// Issue of data. Equal to the 7 bits of the immediate data word t_b - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] - pub iod: u8, -} -impl ConcreteMessage for MsgEphemerisGlo { - const MESSAGE_TYPE: u16 = 139; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO"; -} - -impl SbpMessage for MsgEphemerisGlo { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisSbasDepA { + const MIN_LEN: usize = ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.a_gf0) + + WireFormat::len(&self.a_gf1) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.a_gf0, buf); + WireFormat::write(&self.a_gf1, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisSbasDepA { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + a_gf0: WireFormat::parse_unchecked(buf), + a_gf1: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGlo { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGlo(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ephemeris_sbas_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// This observation message has been deprecated in favor of ephemeris message + /// using floats for size reduction. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgEphemerisSbasDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Values common for all ephemeris types + #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] + pub common: EphemerisCommonContentDepB, + /// Position of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] + pub pos: [f64; 3], + /// Velocity of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] + pub vel: [f64; 3], + /// Acceleration of the GEO at time toe + #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] + pub acc: [f64; 3], + /// Time offset of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] + pub a_gf0: f64, + /// Drift of the GEO clock w.r.t. SBAS Network Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] + pub a_gf1: f64, + } + + impl ConcreteMessage for MsgEphemerisSbasDepB { + const MESSAGE_TYPE: u16 = 132; + const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS_DEP_B"; + } + + impl SbpMessage for MsgEphemerisSbasDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGlo { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f32; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.gamma) - + WireFormat::len(&self.tau) - + WireFormat::len(&self.d_tau) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.fcn) - + WireFormat::len(&self.iod) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.gamma, buf); - WireFormat::write(&self.tau, buf); - WireFormat::write(&self.d_tau, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.fcn, buf); - WireFormat::write(&self.iod, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGlo { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - gamma: WireFormat::parse_unchecked(buf), - tau: WireFormat::parse_unchecked(buf), - d_tau: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - fcn: WireFormat::parse_unchecked(buf), - iod: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgEphemerisSbasDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgEphemerisSbasDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for GLO -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GLO satellite position, velocity, and clock offset. -/// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of -/// immediate information (ephemeris parameters)" for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGloDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepA, - /// Relative deviation of predicted carrier frequency from nominal - #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] - pub gamma: f64, - /// Correction to the SV time - #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] - pub tau: f64, - /// Position of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity vector of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], -} - -impl ConcreteMessage for MsgEphemerisGloDepA { - const MESSAGE_TYPE: u16 = 131; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_A"; -} -impl SbpMessage for MsgEphemerisGloDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgEphemerisSbasDepB { + const MIN_LEN: usize = ::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + <[f64; 3] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.common) + + WireFormat::len(&self.pos) + + WireFormat::len(&self.vel) + + WireFormat::len(&self.acc) + + WireFormat::len(&self.a_gf0) + + WireFormat::len(&self.a_gf1) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.common, buf); + WireFormat::write(&self.pos, buf); + WireFormat::write(&self.vel, buf); + WireFormat::write(&self.acc, buf); + WireFormat::write(&self.a_gf0, buf); + WireFormat::write(&self.a_gf1, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgEphemerisSbasDepB { + sender_id: None, + common: WireFormat::parse_unchecked(buf), + pos: WireFormat::parse_unchecked(buf), + vel: WireFormat::parse_unchecked(buf), + acc: WireFormat::parse_unchecked(buf), + a_gf0: WireFormat::parse_unchecked(buf), + a_gf1: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGloDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGloDepA(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_glo_biases { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GLONASS L1/L2 Code-Phase biases + /// + /// The GLONASS L1/L2 Code-Phase biases allows to perform GPS+GLONASS integer + /// ambiguity resolution for baselines with mixed receiver types (e.g. + /// receiver of different manufacturers). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGloBiases { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GLONASS FDMA signals mask + #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] + pub mask: u8, + /// GLONASS L1 C/A Code-Phase Bias + #[cfg_attr(feature = "serde", serde(rename(serialize = "l1ca_bias")))] + pub l1ca_bias: i16, + /// GLONASS L1 P Code-Phase Bias + #[cfg_attr(feature = "serde", serde(rename(serialize = "l1p_bias")))] + pub l1p_bias: i16, + /// GLONASS L2 C/A Code-Phase Bias + #[cfg_attr(feature = "serde", serde(rename(serialize = "l2ca_bias")))] + pub l2ca_bias: i16, + /// GLONASS L2 P Code-Phase Bias + #[cfg_attr(feature = "serde", serde(rename(serialize = "l2p_bias")))] + pub l2p_bias: i16, + } + + impl ConcreteMessage for MsgGloBiases { + const MESSAGE_TYPE: u16 = 117; + const MESSAGE_NAME: &'static str = "MSG_GLO_BIASES"; + } + + impl SbpMessage for MsgGloBiases { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGloDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.gamma) - + WireFormat::len(&self.tau) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.gamma, buf); - WireFormat::write(&self.tau, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGloDepA { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - gamma: WireFormat::parse_unchecked(buf), - tau: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgGloBiases { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGloBiases(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Satellite broadcast ephemeris for GLO -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GLO satellite position, velocity, and clock offset. -/// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of -/// immediate information (ephemeris parameters)" for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGloDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepB, - /// Relative deviation of predicted carrier frequency from nominal - #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] - pub gamma: f64, - /// Correction to the SV time - #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] - pub tau: f64, - /// Position of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity vector of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], + impl WireFormat for MsgGloBiases { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mask) + + WireFormat::len(&self.l1ca_bias) + + WireFormat::len(&self.l1p_bias) + + WireFormat::len(&self.l2ca_bias) + + WireFormat::len(&self.l2p_bias) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mask, buf); + WireFormat::write(&self.l1ca_bias, buf); + WireFormat::write(&self.l1p_bias, buf); + WireFormat::write(&self.l2ca_bias, buf); + WireFormat::write(&self.l2p_bias, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGloBiases { + sender_id: None, + mask: WireFormat::parse_unchecked(buf), + l1ca_bias: WireFormat::parse_unchecked(buf), + l1p_bias: WireFormat::parse_unchecked(buf), + l2ca_bias: WireFormat::parse_unchecked(buf), + l2p_bias: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgEphemerisGloDepB { - const MESSAGE_TYPE: u16 = 133; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_B"; -} +pub mod msg_gnss_capb { + #![allow(unused_imports)] -impl SbpMessage for MsgEphemerisGloDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// GNSS capabilities + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGnssCapb { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Navigation Message Correction Table Validity Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] + pub t_nmct: GpsTimeSec, + /// GNSS capabilities masks + #[cfg_attr(feature = "serde", serde(rename(serialize = "gc")))] + pub gc: GnssCapb, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgGnssCapb { + const MESSAGE_TYPE: u16 = 150; + const MESSAGE_NAME: &'static str = "MSG_GNSS_CAPB"; } -} -impl TryFrom for MsgEphemerisGloDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGloDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgGnssCapb { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGloDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.gamma) - + WireFormat::len(&self.tau) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.gamma, buf); - WireFormat::write(&self.tau, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGloDepB { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - gamma: WireFormat::parse_unchecked(buf), - tau: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgGnssCapb { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGnssCapb(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for GLO -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GLO satellite position, velocity, and clock offset. -/// Please see the GLO ICD 5.1 "Table 4.5 Characteristics of words of -/// immediate information (ephemeris parameters)" for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGloDepC { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepB, - /// Relative deviation of predicted carrier frequency from nominal - #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] - pub gamma: f64, - /// Correction to the SV time - #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] - pub tau: f64, - /// Equipment delay between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] - pub d_tau: f64, - /// Position of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity vector of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], - /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] - pub fcn: u8, -} - -impl ConcreteMessage for MsgEphemerisGloDepC { - const MESSAGE_TYPE: u16 = 135; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_C"; -} -impl SbpMessage for MsgEphemerisGloDepC { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgGnssCapb { + const MIN_LEN: usize = + ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_nmct) + WireFormat::len(&self.gc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_nmct, buf); + WireFormat::write(&self.gc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGnssCapb { + sender_id: None, + t_nmct: WireFormat::parse_unchecked(buf), + gc: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGloDepC { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGloDepC(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_group_delay { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Group Delay + /// + /// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGroupDelay { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Data Predict Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] + pub t_op: GpsTimeSec, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// bit-field indicating validity of the values, LSB indicating tgd validity + /// etc. 1 = value is valid, 0 = value is not valid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] + pub isc_l1ca: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] + pub isc_l2c: i16, + } + + impl ConcreteMessage for MsgGroupDelay { + const MESSAGE_TYPE: u16 = 148; + const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY"; + } + + impl SbpMessage for MsgGroupDelay { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGloDepC { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.gamma) - + WireFormat::len(&self.tau) - + WireFormat::len(&self.d_tau) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.fcn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.gamma, buf); - WireFormat::write(&self.tau, buf); - WireFormat::write(&self.d_tau, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.fcn, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGloDepC { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - gamma: WireFormat::parse_unchecked(buf), - tau: WireFormat::parse_unchecked(buf), - d_tau: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - fcn: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgGroupDelay { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGroupDelay(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Deprecated -/// -/// This observation message has been deprecated in favor of ephemeris message -/// using floats for size reduction. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGloDepD { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepB, - /// Relative deviation of predicted carrier frequency from nominal - #[cfg_attr(feature = "serde", serde(rename(serialize = "gamma")))] - pub gamma: f64, - /// Correction to the SV time - #[cfg_attr(feature = "serde", serde(rename(serialize = "tau")))] - pub tau: f64, - /// Equipment delay between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "d_tau")))] - pub d_tau: f64, - /// Position of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity vector of the SV at tb in PZ-90.02 coordinates system - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration vector of the SV at tb in PZ-90.02 coordinates sys - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], - /// Frequency slot. FCN+8 (that is \[1..14\]). 0 or 0xFF for invalid - #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] - pub fcn: u8, - /// Issue of data. Equal to the 7 bits of the immediate data word t_b - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] - pub iod: u8, -} - -impl ConcreteMessage for MsgEphemerisGloDepD { - const MESSAGE_TYPE: u16 = 136; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GLO_DEP_D"; -} -impl SbpMessage for MsgEphemerisGloDepD { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgGroupDelay { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_op) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.isc_l1ca) + + WireFormat::len(&self.isc_l2c) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_op, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.isc_l1ca, buf); + WireFormat::write(&self.isc_l2c, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGroupDelay { + sender_id: None, + t_op: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + isc_l1ca: WireFormat::parse_unchecked(buf), + isc_l2c: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGloDepD { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGloDepD(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_group_delay_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Group Delay + /// + /// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGroupDelayDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Data Predict Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] + pub t_op: GpsTimeDep, + /// Satellite number + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + /// bit-field indicating validity of the values, LSB indicating tgd validity + /// etc. 1 = value is valid, 0 = value is not valid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] + pub isc_l1ca: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] + pub isc_l2c: i16, + } + + impl ConcreteMessage for MsgGroupDelayDepA { + const MESSAGE_TYPE: u16 = 146; + const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY_DEP_A"; + } + + impl SbpMessage for MsgGroupDelayDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGloDepD { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.gamma) - + WireFormat::len(&self.tau) - + WireFormat::len(&self.d_tau) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.fcn) - + WireFormat::len(&self.iod) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.gamma, buf); - WireFormat::write(&self.tau, buf); - WireFormat::write(&self.d_tau, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.fcn, buf); - WireFormat::write(&self.iod, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGloDepD { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - gamma: WireFormat::parse_unchecked(buf), - tau: WireFormat::parse_unchecked(buf), - d_tau: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - fcn: WireFormat::parse_unchecked(buf), - iod: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgGroupDelayDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGroupDelayDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for GPS -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GPS satellite position, velocity, and clock offset. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Table 20-III) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGps { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f32, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f32, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f32, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f32, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f32, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f32, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f32, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f32, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f32, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f32, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} -impl ConcreteMessage for MsgEphemerisGps { - const MESSAGE_TYPE: u16 = 138; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS"; -} - -impl SbpMessage for MsgEphemerisGps { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgGroupDelayDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_op) + + WireFormat::len(&self.prn) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.isc_l1ca) + + WireFormat::len(&self.isc_l2c) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_op, buf); + WireFormat::write(&self.prn, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.isc_l1ca, buf); + WireFormat::write(&self.isc_l2c, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGroupDelayDepA { + sender_id: None, + t_op: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + isc_l1ca: WireFormat::parse_unchecked(buf), + isc_l2c: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGps { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGps(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_group_delay_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Group Delay + /// + /// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGroupDelayDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Data Predict Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] + pub t_op: GpsTimeSec, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// bit-field indicating validity of the values, LSB indicating tgd validity + /// etc. 1 = value is valid, 0 = value is not valid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] + pub valid: u8, + #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] + pub tgd: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] + pub isc_l1ca: i16, + #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] + pub isc_l2c: i16, + } + + impl ConcreteMessage for MsgGroupDelayDepB { + const MESSAGE_TYPE: u16 = 147; + const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY_DEP_B"; + } + + impl SbpMessage for MsgGroupDelayDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGps { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGps { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgGroupDelayDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGroupDelayDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for GPS -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate GPS satellite position, velocity, and clock offset. -/// Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD- -/// GPS-200, Table 20-III) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGpsDepE { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepA, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeDep, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} - -impl ConcreteMessage for MsgEphemerisGpsDepE { - const MESSAGE_TYPE: u16 = 129; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS_DEP_E"; -} -impl SbpMessage for MsgEphemerisGpsDepE { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgGroupDelayDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_op) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.valid) + + WireFormat::len(&self.tgd) + + WireFormat::len(&self.isc_l1ca) + + WireFormat::len(&self.isc_l2c) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_op, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.valid, buf); + WireFormat::write(&self.tgd, buf); + WireFormat::write(&self.isc_l1ca, buf); + WireFormat::write(&self.isc_l2c, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGroupDelayDepB { + sender_id: None, + t_op: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + valid: WireFormat::parse_unchecked(buf), + tgd: WireFormat::parse_unchecked(buf), + isc_l1ca: WireFormat::parse_unchecked(buf), + isc_l2c: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgEphemerisGpsDepE { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGpsDepE(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_iono { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Iono corrections + /// + /// The ionospheric parameters which allow the "L1 only" or "L2 only" user to + /// utilize the ionospheric model for computation of the ionospheric delay. + /// Please see ICD-GPS-200 (Chapter 20.3.3.5.1.7) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgIono { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Navigation Message Correction Table Validity Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] + pub t_nmct: GpsTimeSec, + #[cfg_attr(feature = "serde", serde(rename(serialize = "a0")))] + pub a0: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "a1")))] + pub a1: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "a2")))] + pub a2: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "a3")))] + pub a3: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "b0")))] + pub b0: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "b1")))] + pub b1: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "b2")))] + pub b2: f64, + #[cfg_attr(feature = "serde", serde(rename(serialize = "b3")))] + pub b3: f64, + } + + impl ConcreteMessage for MsgIono { + const MESSAGE_TYPE: u16 = 144; + const MESSAGE_NAME: &'static str = "MSG_IONO"; + } + + impl SbpMessage for MsgIono { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgEphemerisGpsDepE { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGpsDepE { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgIono { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgIono(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Deprecated -/// -/// This observation message has been deprecated in favor of ephemeris message -/// using floats for size reduction. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisGpsDepF { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepB, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f64, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f64, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f64, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f64, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f64, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f64, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f64, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f64, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f64, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f64, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} - -impl ConcreteMessage for MsgEphemerisGpsDepF { - const MESSAGE_TYPE: u16 = 134; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_GPS_DEP_F"; + impl WireFormat for MsgIono { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_nmct) + + WireFormat::len(&self.a0) + + WireFormat::len(&self.a1) + + WireFormat::len(&self.a2) + + WireFormat::len(&self.a3) + + WireFormat::len(&self.b0) + + WireFormat::len(&self.b1) + + WireFormat::len(&self.b2) + + WireFormat::len(&self.b3) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_nmct, buf); + WireFormat::write(&self.a0, buf); + WireFormat::write(&self.a1, buf); + WireFormat::write(&self.a2, buf); + WireFormat::write(&self.a3, buf); + WireFormat::write(&self.b0, buf); + WireFormat::write(&self.b1, buf); + WireFormat::write(&self.b2, buf); + WireFormat::write(&self.b3, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgIono { + sender_id: None, + t_nmct: WireFormat::parse_unchecked(buf), + a0: WireFormat::parse_unchecked(buf), + a1: WireFormat::parse_unchecked(buf), + a2: WireFormat::parse_unchecked(buf), + a3: WireFormat::parse_unchecked(buf), + b0: WireFormat::parse_unchecked(buf), + b1: WireFormat::parse_unchecked(buf), + b2: WireFormat::parse_unchecked(buf), + b3: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgEphemerisGpsDepF { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_obs { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GPS satellite observations + /// + /// The GPS observations message reports all the raw pseudorange and carrier + /// phase observations for the satellites being tracked by the device. Carrier + /// phase observation here is represented as a 40-bit fixed point number with + /// Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional + /// cycles). The observations are be interoperable with 3rd party receivers + /// and conform with typical RTCMv3 GNSS observations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgObs { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a GPS observation message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: ObservationHeader, + /// Pseudorange and carrier phase observation for a satellite being tracked. + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] + pub obs: Vec, + } + + impl ConcreteMessage for MsgObs { + const MESSAGE_TYPE: u16 = 74; + const MESSAGE_NAME: &'static str = "MSG_OBS"; + } + + impl SbpMessage for MsgObs { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.header.t.tow as f64) / 1000.0; + let wn: i16 = match self.header.t.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Base(gps_time.into()))) + } } -} -impl TryFrom for MsgEphemerisGpsDepF { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisGpsDepF(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgObs { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgObs(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgEphemerisGpsDepF { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisGpsDepF { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgObs { + const MIN_LEN: usize = ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgObs { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + obs: WireFormat::parse_unchecked(buf), + } } } } -/// Satellite broadcast ephemeris for QZSS -/// -/// The ephemeris message returns a set of satellite orbit parameters that is -/// used to calculate QZSS satellite position, velocity, and clock offset. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisQzss { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// Group delay differential between L1 and L2 - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: f32, - /// Amplitude of the sine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rs")))] - pub c_rs: f32, - /// Amplitude of the cosine harmonic correction term to the orbit radius - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_rc")))] - pub c_rc: f32, - /// Amplitude of the cosine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_uc")))] - pub c_uc: f32, - /// Amplitude of the sine harmonic correction term to the argument of - /// latitude - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_us")))] - pub c_us: f32, - /// Amplitude of the cosine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_ic")))] - pub c_ic: f32, - /// Amplitude of the sine harmonic correction term to the angle of - /// inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "c_is")))] - pub c_is: f32, - /// Mean motion difference - #[cfg_attr(feature = "serde", serde(rename(serialize = "dn")))] - pub dn: f64, - /// Mean anomaly at reference time - #[cfg_attr(feature = "serde", serde(rename(serialize = "m0")))] - pub m0: f64, - /// Eccentricity of satellite orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "ecc")))] - pub ecc: f64, - /// Square root of the semi-major axis of orbit - #[cfg_attr(feature = "serde", serde(rename(serialize = "sqrta")))] - pub sqrta: f64, - /// Longitude of ascending node of orbit plane at weekly epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "omega0")))] - pub omega0: f64, - /// Rate of right ascension - #[cfg_attr(feature = "serde", serde(rename(serialize = "omegadot")))] - pub omegadot: f64, - /// Argument of perigee - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: f64, - /// Inclination - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc")))] - pub inc: f64, - /// Inclination first derivative - #[cfg_attr(feature = "serde", serde(rename(serialize = "inc_dot")))] - pub inc_dot: f64, - /// Polynomial clock correction coefficient (clock bias) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af0")))] - pub af0: f32, - /// Polynomial clock correction coefficient (clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af1")))] - pub af1: f32, - /// Polynomial clock correction coefficient (rate of clock drift) - #[cfg_attr(feature = "serde", serde(rename(serialize = "af2")))] - pub af2: f32, - /// Clock reference - #[cfg_attr(feature = "serde", serde(rename(serialize = "toc")))] - pub toc: GpsTimeSec, - /// Issue of ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iode")))] - pub iode: u8, - /// Issue of clock data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iodc")))] - pub iodc: u16, -} +pub mod msg_obs_dep_a { + #![allow(unused_imports)] -impl ConcreteMessage for MsgEphemerisQzss { - const MESSAGE_TYPE: u16 = 142; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_QZSS"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgEphemerisQzss { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgObsDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a GPS observation message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: ObservationHeaderDep, + /// Pseudorange and carrier phase observation for a satellite being tracked. + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] + pub obs: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgObsDepA { + const MESSAGE_TYPE: u16 = 69; + const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_A"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgObsDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.header.t.tow as f64) / 1000.0; + let wn: i16 = match self.header.t.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgEphemerisQzss { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisQzss(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgObsDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgObsDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgEphemerisQzss { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.c_rs) - + WireFormat::len(&self.c_rc) - + WireFormat::len(&self.c_uc) - + WireFormat::len(&self.c_us) - + WireFormat::len(&self.c_ic) - + WireFormat::len(&self.c_is) - + WireFormat::len(&self.dn) - + WireFormat::len(&self.m0) - + WireFormat::len(&self.ecc) - + WireFormat::len(&self.sqrta) - + WireFormat::len(&self.omega0) - + WireFormat::len(&self.omegadot) - + WireFormat::len(&self.w) - + WireFormat::len(&self.inc) - + WireFormat::len(&self.inc_dot) - + WireFormat::len(&self.af0) - + WireFormat::len(&self.af1) - + WireFormat::len(&self.af2) - + WireFormat::len(&self.toc) - + WireFormat::len(&self.iode) - + WireFormat::len(&self.iodc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.c_rs, buf); - WireFormat::write(&self.c_rc, buf); - WireFormat::write(&self.c_uc, buf); - WireFormat::write(&self.c_us, buf); - WireFormat::write(&self.c_ic, buf); - WireFormat::write(&self.c_is, buf); - WireFormat::write(&self.dn, buf); - WireFormat::write(&self.m0, buf); - WireFormat::write(&self.ecc, buf); - WireFormat::write(&self.sqrta, buf); - WireFormat::write(&self.omega0, buf); - WireFormat::write(&self.omegadot, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.inc, buf); - WireFormat::write(&self.inc_dot, buf); - WireFormat::write(&self.af0, buf); - WireFormat::write(&self.af1, buf); - WireFormat::write(&self.af2, buf); - WireFormat::write(&self.toc, buf); - WireFormat::write(&self.iode, buf); - WireFormat::write(&self.iodc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisQzss { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - c_rs: WireFormat::parse_unchecked(buf), - c_rc: WireFormat::parse_unchecked(buf), - c_uc: WireFormat::parse_unchecked(buf), - c_us: WireFormat::parse_unchecked(buf), - c_ic: WireFormat::parse_unchecked(buf), - c_is: WireFormat::parse_unchecked(buf), - dn: WireFormat::parse_unchecked(buf), - m0: WireFormat::parse_unchecked(buf), - ecc: WireFormat::parse_unchecked(buf), - sqrta: WireFormat::parse_unchecked(buf), - omega0: WireFormat::parse_unchecked(buf), - omegadot: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - inc: WireFormat::parse_unchecked(buf), - inc_dot: WireFormat::parse_unchecked(buf), - af0: WireFormat::parse_unchecked(buf), - af1: WireFormat::parse_unchecked(buf), - af2: WireFormat::parse_unchecked(buf), - toc: WireFormat::parse_unchecked(buf), - iode: WireFormat::parse_unchecked(buf), - iodc: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgObsDepA { + const MIN_LEN: usize = ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgObsDepA { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + obs: WireFormat::parse_unchecked(buf), + } } } } -/// Satellite broadcast ephemeris for SBAS -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisSbas { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContent, - /// Position of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f32; 3], - /// Acceleration of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f32; 3], - /// Time offset of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] - pub a_gf0: f32, - /// Drift of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] - pub a_gf1: f32, -} +pub mod msg_obs_dep_b { + #![allow(unused_imports)] -impl ConcreteMessage for MsgEphemerisSbas { - const MESSAGE_TYPE: u16 = 140; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgEphemerisSbas { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Deprecated + /// + /// This observation message has been deprecated in favor of observations that + /// are more interoperable. This message should be used for observations + /// referenced to a nominal pseudorange which are not interoperable with most + /// 3rd party GNSS receivers or typical RTCMv3 observations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgObsDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a GPS observation message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: ObservationHeaderDep, + /// Pseudorange and carrier phase observation for a satellite being tracked. + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] + pub obs: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgObsDepB { + const MESSAGE_TYPE: u16 = 67; + const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_B"; } -} -impl TryFrom for MsgEphemerisSbas { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisSbas(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgObsDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.header.t.tow as f64) / 1000.0; + let wn: i16 = match self.header.t.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgEphemerisSbas { - const MIN_LEN: usize = ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f32; 3] as WireFormat>::MIN_LEN - + <[f32; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.a_gf0) - + WireFormat::len(&self.a_gf1) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.a_gf0, buf); - WireFormat::write(&self.a_gf1, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisSbas { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - a_gf0: WireFormat::parse_unchecked(buf), - a_gf1: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgObsDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgObsDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Satellite broadcast ephemeris for SBAS -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisSbasDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepA, - /// Position of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], - /// Time offset of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] - pub a_gf0: f64, - /// Drift of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] - pub a_gf1: f64, -} -impl ConcreteMessage for MsgEphemerisSbasDepA { - const MESSAGE_TYPE: u16 = 130; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS_DEP_A"; + impl WireFormat for MsgObsDepB { + const MIN_LEN: usize = ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgObsDepB { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + obs: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgEphemerisSbasDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_obs_dep_c { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// The GPS observations message reports all the raw pseudorange and carrier + /// phase observations for the satellites being tracked by the device. Carrier + /// phase observation here is represented as a 40-bit fixed point number with + /// Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional + /// cycles). The observations are interoperable with 3rd party receivers and + /// conform with typical RTCMv3 GNSS observations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgObsDepC { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a GPS observation message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: ObservationHeaderDep, + /// Pseudorange and carrier phase observation for a satellite being tracked. + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] + pub obs: Vec, + } + + impl ConcreteMessage for MsgObsDepC { + const MESSAGE_TYPE: u16 = 73; + const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_C"; + } + + impl SbpMessage for MsgObsDepC { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.header.t.tow as f64) / 1000.0; + let wn: i16 = match self.header.t.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } -} -impl TryFrom for MsgEphemerisSbasDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisSbasDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgObsDepC { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgObsDepC(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgEphemerisSbasDepA { - const MIN_LEN: usize = ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.a_gf0) - + WireFormat::len(&self.a_gf1) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.a_gf0, buf); - WireFormat::write(&self.a_gf1, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisSbasDepA { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - a_gf0: WireFormat::parse_unchecked(buf), - a_gf1: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgObsDepC { + const MIN_LEN: usize = ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgObsDepC { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + obs: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -/// -/// This observation message has been deprecated in favor of ephemeris message -/// using floats for size reduction. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgEphemerisSbasDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Values common for all ephemeris types - #[cfg_attr(feature = "serde", serde(rename(serialize = "common")))] - pub common: EphemerisCommonContentDepB, - /// Position of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "pos")))] - pub pos: [f64; 3], - /// Velocity of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "vel")))] - pub vel: [f64; 3], - /// Acceleration of the GEO at time toe - #[cfg_attr(feature = "serde", serde(rename(serialize = "acc")))] - pub acc: [f64; 3], - /// Time offset of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf0")))] - pub a_gf0: f64, - /// Drift of the GEO clock w.r.t. SBAS Network Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "a_gf1")))] - pub a_gf1: f64, -} +pub mod msg_osr { + #![allow(unused_imports)] -impl ConcreteMessage for MsgEphemerisSbasDepB { - const MESSAGE_TYPE: u16 = 132; - const MESSAGE_NAME: &'static str = "MSG_EPHEMERIS_SBAS_DEP_B"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgEphemerisSbasDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// OSR corrections + /// + /// The OSR message contains network corrections in an observation-like + /// format. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgOsr { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a GPS observation message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: ObservationHeader, + /// Network correction for a satellite signal. + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] + pub obs: Vec, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgOsr { + const MESSAGE_TYPE: u16 = 1600; + const MESSAGE_NAME: &'static str = "MSG_OSR"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgOsr { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.header.t.tow as f64) / 1000.0; + let wn: i16 = match self.header.t.wn.try_into() { + Ok(wn) => wn, + Err(e) => return Some(Err(e.into())), + }; + let gps_time = match time::GpsTime::new(wn, tow_s) { + Ok(gps_time) => gps_time, + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Base(gps_time.into()))) + } } -} -impl TryFrom for MsgEphemerisSbasDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgEphemerisSbasDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgOsr { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgOsr(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgEphemerisSbasDepB { - const MIN_LEN: usize = ::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + <[f64; 3] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.common) - + WireFormat::len(&self.pos) - + WireFormat::len(&self.vel) - + WireFormat::len(&self.acc) - + WireFormat::len(&self.a_gf0) - + WireFormat::len(&self.a_gf1) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.common, buf); - WireFormat::write(&self.pos, buf); - WireFormat::write(&self.vel, buf); - WireFormat::write(&self.acc, buf); - WireFormat::write(&self.a_gf0, buf); - WireFormat::write(&self.a_gf1, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgEphemerisSbasDepB { - sender_id: None, - common: WireFormat::parse_unchecked(buf), - pos: WireFormat::parse_unchecked(buf), - vel: WireFormat::parse_unchecked(buf), - acc: WireFormat::parse_unchecked(buf), - a_gf0: WireFormat::parse_unchecked(buf), - a_gf1: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgOsr { + const MIN_LEN: usize = ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgOsr { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + obs: WireFormat::parse_unchecked(buf), + } } } } -/// GLONASS L1/L2 Code-Phase biases -/// -/// The GLONASS L1/L2 Code-Phase biases allows to perform GPS+GLONASS integer -/// ambiguity resolution for baselines with mixed receiver types (e.g. -/// receiver of different manufacturers). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGloBiases { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GLONASS FDMA signals mask - #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] - pub mask: u8, - /// GLONASS L1 C/A Code-Phase Bias - #[cfg_attr(feature = "serde", serde(rename(serialize = "l1ca_bias")))] - pub l1ca_bias: i16, - /// GLONASS L1 P Code-Phase Bias - #[cfg_attr(feature = "serde", serde(rename(serialize = "l1p_bias")))] - pub l1p_bias: i16, - /// GLONASS L2 C/A Code-Phase Bias - #[cfg_attr(feature = "serde", serde(rename(serialize = "l2ca_bias")))] - pub l2ca_bias: i16, - /// GLONASS L2 P Code-Phase Bias - #[cfg_attr(feature = "serde", serde(rename(serialize = "l2p_bias")))] - pub l2p_bias: i16, -} +pub mod msg_sv_az_el { + #![allow(unused_imports)] -impl ConcreteMessage for MsgGloBiases { - const MESSAGE_TYPE: u16 = 117; - const MESSAGE_NAME: &'static str = "MSG_GLO_BIASES"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgGloBiases { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Satellite azimuths and elevations + /// + /// Azimuth and elevation angles of all the visible satellites that the device + /// does have ephemeris or almanac for. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSvAzEl { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Azimuth and elevation per satellite + #[cfg_attr(feature = "serde", serde(rename(serialize = "azel")))] + pub azel: Vec, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgSvAzEl { + const MESSAGE_TYPE: u16 = 151; + const MESSAGE_NAME: &'static str = "MSG_SV_AZ_EL"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgSvAzEl { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgGloBiases { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGloBiases(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSvAzEl { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSvAzEl(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgGloBiases { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mask) - + WireFormat::len(&self.l1ca_bias) - + WireFormat::len(&self.l1p_bias) - + WireFormat::len(&self.l2ca_bias) - + WireFormat::len(&self.l2p_bias) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mask, buf); - WireFormat::write(&self.l1ca_bias, buf); - WireFormat::write(&self.l1p_bias, buf); - WireFormat::write(&self.l2ca_bias, buf); - WireFormat::write(&self.l2p_bias, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGloBiases { - sender_id: None, - mask: WireFormat::parse_unchecked(buf), - l1ca_bias: WireFormat::parse_unchecked(buf), - l1p_bias: WireFormat::parse_unchecked(buf), - l2ca_bias: WireFormat::parse_unchecked(buf), - l2p_bias: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSvAzEl { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.azel) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.azel, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSvAzEl { + sender_id: None, + azel: WireFormat::parse_unchecked(buf), + } } } } -/// GNSS capabilities -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGnssCapb { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Navigation Message Correction Table Validity Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] - pub t_nmct: GpsTimeSec, - /// GNSS capabilities masks - #[cfg_attr(feature = "serde", serde(rename(serialize = "gc")))] - pub gc: GnssCapb, -} +pub mod msg_sv_configuration_gps_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgGnssCapb { - const MESSAGE_TYPE: u16 = 150; - const MESSAGE_NAME: &'static str = "MSG_GNSS_CAPB"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgGnssCapb { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// L2C capability mask + /// + /// Please see ICD-GPS-200 (Chapter 20.3.3.5.1.4) for more details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSvConfigurationGpsDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Navigation Message Correction Table Validity Time + #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] + pub t_nmct: GpsTimeSec, + /// L2C capability mask, SV32 bit being MSB, SV1 bit being LSB + #[cfg_attr(feature = "serde", serde(rename(serialize = "l2c_mask")))] + pub l2c_mask: u32, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSvConfigurationGpsDep { + const MESSAGE_TYPE: u16 = 145; + const MESSAGE_NAME: &'static str = "MSG_SV_CONFIGURATION_GPS_DEP"; } -} -impl TryFrom for MsgGnssCapb { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGnssCapb(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSvConfigurationGpsDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgGnssCapb { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_nmct) + WireFormat::len(&self.gc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_nmct, buf); - WireFormat::write(&self.gc, buf); + impl TryFrom for MsgSvConfigurationGpsDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSvConfigurationGpsDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGnssCapb { - sender_id: None, - t_nmct: WireFormat::parse_unchecked(buf), - gc: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSvConfigurationGpsDep { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t_nmct) + WireFormat::len(&self.l2c_mask) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t_nmct, buf); + WireFormat::write(&self.l2c_mask, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSvConfigurationGpsDep { + sender_id: None, + t_nmct: WireFormat::parse_unchecked(buf), + l2c_mask: WireFormat::parse_unchecked(buf), + } } } } -/// Group Delay -/// -/// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGroupDelay { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Data Predict Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] - pub t_op: GpsTimeSec, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// bit-field indicating validity of the values, LSB indicating tgd validity - /// etc. 1 = value is valid, 0 = value is not valid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] - pub isc_l1ca: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] - pub isc_l2c: i16, -} +pub mod observation_header { + #![allow(unused_imports)] -impl ConcreteMessage for MsgGroupDelay { - const MESSAGE_TYPE: u16 = 148; - const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgGroupDelay { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Header for observation message + /// + /// Header of a GNSS observation message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct ObservationHeader { + /// GNSS time of this observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: GpsTime, + /// Total number of observations. First nibble is the size of the sequence + /// (n), second nibble is the zero-indexed counter (ith packet of n) + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_obs")))] + pub n_obs: u8, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} -impl TryFrom for MsgGroupDelay { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGroupDelay(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for ObservationHeader { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t) + WireFormat::len(&self.n_obs) } - } -} - -impl WireFormat for MsgGroupDelay { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_op) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.isc_l1ca) - + WireFormat::len(&self.isc_l2c) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_op, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.isc_l1ca, buf); - WireFormat::write(&self.isc_l2c, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGroupDelay { - sender_id: None, - t_op: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - isc_l1ca: WireFormat::parse_unchecked(buf), - isc_l2c: WireFormat::parse_unchecked(buf), + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t, buf); + WireFormat::write(&self.n_obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + ObservationHeader { + t: WireFormat::parse_unchecked(buf), + n_obs: WireFormat::parse_unchecked(buf), + } } } } -/// Group Delay -/// -/// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGroupDelayDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Data Predict Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] - pub t_op: GpsTimeDep, - /// Satellite number - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, - /// bit-field indicating validity of the values, LSB indicating tgd validity - /// etc. 1 = value is valid, 0 = value is not valid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] - pub isc_l1ca: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] - pub isc_l2c: i16, -} +pub mod observation_header_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgGroupDelayDepA { - const MESSAGE_TYPE: u16 = 146; - const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY_DEP_A"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgGroupDelayDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Header for observation message + /// + /// Header of a GPS observation message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct ObservationHeaderDep { + /// GPS time of this observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: GpsTimeDep, + /// Total number of observations. First nibble is the size of the sequence + /// (n), second nibble is the zero-indexed counter (ith packet of n) + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_obs")))] + pub n_obs: u8, } -} -impl TryFrom for MsgGroupDelayDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGroupDelayDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for ObservationHeaderDep { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.t) + WireFormat::len(&self.n_obs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.t, buf); + WireFormat::write(&self.n_obs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + ObservationHeaderDep { + t: WireFormat::parse_unchecked(buf), + n_obs: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgGroupDelayDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_op) - + WireFormat::len(&self.prn) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.isc_l1ca) - + WireFormat::len(&self.isc_l2c) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_op, buf); - WireFormat::write(&self.prn, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.isc_l1ca, buf); - WireFormat::write(&self.isc_l2c, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGroupDelayDepA { - sender_id: None, - t_op: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - isc_l1ca: WireFormat::parse_unchecked(buf), - isc_l2c: WireFormat::parse_unchecked(buf), +pub mod packed_obs_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GNSS observations for a particular satellite signal + /// + /// Pseudorange and carrier phase observation for a satellite being tracked. + /// The observations are interoperable with 3rd party receivers and conform + /// with typical RTCM 3.1 message GPS/GLO observations. + /// + /// Carrier phase observations are not guaranteed to be aligned to the RINEX 3 + /// or RTCM 3.3 MSM reference signal and no 1/4 cycle adjustments are + /// currently performed. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PackedObsContent { + /// Pseudorange observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Carrier phase observation with typical sign convention. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhase, + /// Doppler observation with typical sign convention. + #[cfg_attr(feature = "serde", serde(rename(serialize = "D")))] + pub d: Doppler, + /// Carrier-to-Noise density. Zero implies invalid cn0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock timer. This value gives an indication of the time for which a + /// signal has maintained continuous phase lock. Whenever a signal has lost + /// and regained lock, this value is reset to zero. It is encoded according + /// to DF402 from the RTCM 10403.2 Amendment 2 specification. Valid values + /// range from 0 to 15 and the most significant nibble is reserved for + /// future use. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u8, + /// Measurement status flags. A bit field of flags providing the status of + /// this observation. If this field is 0 it means only the Cn0 estimate for + /// the signal is valid. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + } + + impl PackedObsContent { + /// Gets the [RaimExclusion][self::RaimExclusion] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RaimExclusion` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RaimExclusion` were added. + pub fn raim_exclusion(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 7, 7).try_into() } - } -} -/// Group Delay -/// -/// Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGroupDelayDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Data Predict Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_op")))] - pub t_op: GpsTimeSec, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// bit-field indicating validity of the values, LSB indicating tgd validity - /// etc. 1 = value is valid, 0 = value is not valid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "valid")))] - pub valid: u8, - #[cfg_attr(feature = "serde", serde(rename(serialize = "tgd")))] - pub tgd: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l1ca")))] - pub isc_l1ca: i16, - #[cfg_attr(feature = "serde", serde(rename(serialize = "isc_l2c")))] - pub isc_l2c: i16, -} + /// Set the bitrange corresponding to the [RaimExclusion][RaimExclusion] of the `flags` bitfield. + pub fn set_raim_exclusion(&mut self, raim_exclusion: RaimExclusion) { + set_bit_range!(&mut self.flags, raim_exclusion, u8, u8, 7, 7); + } -impl ConcreteMessage for MsgGroupDelayDepB { - const MESSAGE_TYPE: u16 = 147; - const MESSAGE_NAME: &'static str = "MSG_GROUP_DELAY_DEP_B"; -} + /// Gets the [DopplerValid][self::DopplerValid] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `DopplerValid` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `DopplerValid` were added. + pub fn doppler_valid(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } -impl SbpMessage for MsgGroupDelayDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Set the bitrange corresponding to the [DopplerValid][DopplerValid] of the `flags` bitfield. + pub fn set_doppler_valid(&mut self, doppler_valid: DopplerValid) { + set_bit_range!(&mut self.flags, doppler_valid, u8, u8, 3, 3); + } -impl TryFrom for MsgGroupDelayDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGroupDelayDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Gets the [HalfCycleAmbiguity][self::HalfCycleAmbiguity] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `HalfCycleAmbiguity` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `HalfCycleAmbiguity` were added. + pub fn halfcycle_ambiguity(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 2).try_into() } - } -} -impl WireFormat for MsgGroupDelayDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_op) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.valid) - + WireFormat::len(&self.tgd) - + WireFormat::len(&self.isc_l1ca) - + WireFormat::len(&self.isc_l2c) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_op, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.valid, buf); - WireFormat::write(&self.tgd, buf); - WireFormat::write(&self.isc_l1ca, buf); - WireFormat::write(&self.isc_l2c, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGroupDelayDepB { - sender_id: None, - t_op: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - valid: WireFormat::parse_unchecked(buf), - tgd: WireFormat::parse_unchecked(buf), - isc_l1ca: WireFormat::parse_unchecked(buf), - isc_l2c: WireFormat::parse_unchecked(buf), + /// Set the bitrange corresponding to the [HalfCycleAmbiguity][HalfCycleAmbiguity] of the `flags` bitfield. + pub fn set_halfcycle_ambiguity(&mut self, halfcycle_ambiguity: HalfCycleAmbiguity) { + set_bit_range!(&mut self.flags, halfcycle_ambiguity, u8, u8, 2, 2); } - } -} -/// Iono corrections -/// -/// The ionospheric parameters which allow the "L1 only" or "L2 only" user to -/// utilize the ionospheric model for computation of the ionospheric delay. -/// Please see ICD-GPS-200 (Chapter 20.3.3.5.1.7) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgIono { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Navigation Message Correction Table Validity Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] - pub t_nmct: GpsTimeSec, - #[cfg_attr(feature = "serde", serde(rename(serialize = "a0")))] - pub a0: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "a1")))] - pub a1: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "a2")))] - pub a2: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "a3")))] - pub a3: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "b0")))] - pub b0: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "b1")))] - pub b1: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "b2")))] - pub b2: f64, - #[cfg_attr(feature = "serde", serde(rename(serialize = "b3")))] - pub b3: f64, -} + /// Gets the [CarrierPhaseValid][self::CarrierPhaseValid] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CarrierPhaseValid` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CarrierPhaseValid` were added. + pub fn carrier_phase_valid(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 1).try_into() + } -impl ConcreteMessage for MsgIono { - const MESSAGE_TYPE: u16 = 144; - const MESSAGE_NAME: &'static str = "MSG_IONO"; -} + /// Set the bitrange corresponding to the [CarrierPhaseValid][CarrierPhaseValid] of the `flags` bitfield. + pub fn set_carrier_phase_valid(&mut self, carrier_phase_valid: CarrierPhaseValid) { + set_bit_range!(&mut self.flags, carrier_phase_valid, u8, u8, 1, 1); + } -impl SbpMessage for MsgIono { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the [PseudorangeValid][self::PseudorangeValid] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PseudorangeValid` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PseudorangeValid` were added. + pub fn pseudorange_valid(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 0, 0).try_into() + } -impl TryFrom for MsgIono { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgIono(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Set the bitrange corresponding to the [PseudorangeValid][PseudorangeValid] of the `flags` bitfield. + pub fn set_pseudorange_valid(&mut self, pseudorange_valid: PseudorangeValid) { + set_bit_range!(&mut self.flags, pseudorange_valid, u8, u8, 0, 0); } } -} -impl WireFormat for MsgIono { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_nmct) - + WireFormat::len(&self.a0) - + WireFormat::len(&self.a1) - + WireFormat::len(&self.a2) - + WireFormat::len(&self.a3) - + WireFormat::len(&self.b0) - + WireFormat::len(&self.b1) - + WireFormat::len(&self.b2) - + WireFormat::len(&self.b3) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_nmct, buf); - WireFormat::write(&self.a0, buf); - WireFormat::write(&self.a1, buf); - WireFormat::write(&self.a2, buf); - WireFormat::write(&self.a3, buf); - WireFormat::write(&self.b0, buf); - WireFormat::write(&self.b1, buf); - WireFormat::write(&self.b2, buf); - WireFormat::write(&self.b3, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgIono { - sender_id: None, - t_nmct: WireFormat::parse_unchecked(buf), - a0: WireFormat::parse_unchecked(buf), - a1: WireFormat::parse_unchecked(buf), - a2: WireFormat::parse_unchecked(buf), - a3: WireFormat::parse_unchecked(buf), - b0: WireFormat::parse_unchecked(buf), - b1: WireFormat::parse_unchecked(buf), - b2: WireFormat::parse_unchecked(buf), - b3: WireFormat::parse_unchecked(buf), + impl WireFormat for PackedObsContent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.p) + + WireFormat::len(&self.l) + + WireFormat::len(&self.d) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.p, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.d, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PackedObsContent { + p: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + d: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } } } -} - -/// GPS satellite observations -/// -/// The GPS observations message reports all the raw pseudorange and carrier -/// phase observations for the satellites being tracked by the device. Carrier -/// phase observation here is represented as a 40-bit fixed point number with -/// Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional -/// cycles). The observations are be interoperable with 3rd party receivers -/// and conform with typical RTCMv3 GNSS observations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgObs { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a GPS observation message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: ObservationHeader, - /// Pseudorange and carrier phase observation for a satellite being tracked. - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] - pub obs: Vec, -} -impl ConcreteMessage for MsgObs { - const MESSAGE_TYPE: u16 = 74; - const MESSAGE_NAME: &'static str = "MSG_OBS"; -} + /// RAIM exclusion + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RaimExclusion { + /// No exclusion + NoExclusion = 0, -impl SbpMessage for MsgObs { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Measurement was excluded by SPP RAIM, use with care + MeasurementWasExcludedBySppRaimUseWithCare = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.header.t.tow as f64) / 1000.0; - let wn: i16 = match self.header.t.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Base(gps_time.into()))) - } -} -impl TryFrom for MsgObs { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgObs(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for RaimExclusion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RaimExclusion::NoExclusion => f.write_str("No exclusion"), + RaimExclusion::MeasurementWasExcludedBySppRaimUseWithCare => { + f.write_str("Measurement was excluded by SPP RAIM, use with care") + } + } } } -} -impl WireFormat for MsgObs { - const MIN_LEN: usize = - ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.obs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.obs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgObs { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - obs: WireFormat::parse_unchecked(buf), + impl TryFrom for RaimExclusion { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RaimExclusion::NoExclusion), + 1 => Ok(RaimExclusion::MeasurementWasExcludedBySppRaimUseWithCare), + i => Err(i), + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgObsDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a GPS observation message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: ObservationHeaderDep, - /// Pseudorange and carrier phase observation for a satellite being tracked. - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] - pub obs: Vec, -} - -impl ConcreteMessage for MsgObsDepA { - const MESSAGE_TYPE: u16 = 69; - const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_A"; -} + /// Doppler valid + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum DopplerValid { + /// Invalid doppler measurement + InvalidDopplerMeasurement = 0, -impl SbpMessage for MsgObsDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Valid doppler measurement + ValidDopplerMeasurement = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.header.t.tow as f64) / 1000.0; - let wn: i16 = match self.header.t.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgObsDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgObsDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for DopplerValid { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DopplerValid::InvalidDopplerMeasurement => { + f.write_str("Invalid doppler measurement") + } + DopplerValid::ValidDopplerMeasurement => f.write_str("Valid doppler measurement"), + } } } -} -impl WireFormat for MsgObsDepA { - const MIN_LEN: usize = ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.obs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.obs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgObsDepA { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - obs: WireFormat::parse_unchecked(buf), + impl TryFrom for DopplerValid { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(DopplerValid::InvalidDopplerMeasurement), + 1 => Ok(DopplerValid::ValidDopplerMeasurement), + i => Err(i), + } } } -} - -/// Deprecated -/// -/// This observation message has been deprecated in favor of observations that -/// are more interoperable. This message should be used for observations -/// referenced to a nominal pseudorange which are not interoperable with most -/// 3rd party GNSS receivers or typical RTCMv3 observations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgObsDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a GPS observation message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: ObservationHeaderDep, - /// Pseudorange and carrier phase observation for a satellite being tracked. - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] - pub obs: Vec, -} -impl ConcreteMessage for MsgObsDepB { - const MESSAGE_TYPE: u16 = 67; - const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_B"; -} + /// Half-cycle ambiguity + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum HalfCycleAmbiguity { + /// Half cycle phase ambiguity unresolved + HalfCyclePhaseAmbiguityUnresolved = 0, -impl SbpMessage for MsgObsDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Half cycle phase ambiguity resolved + HalfCyclePhaseAmbiguityResolved = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.header.t.tow as f64) / 1000.0; - let wn: i16 = match self.header.t.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) - } -} -impl TryFrom for MsgObsDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgObsDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for HalfCycleAmbiguity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + HalfCycleAmbiguity::HalfCyclePhaseAmbiguityUnresolved => { + f.write_str("Half cycle phase ambiguity unresolved") + } + HalfCycleAmbiguity::HalfCyclePhaseAmbiguityResolved => { + f.write_str("Half cycle phase ambiguity resolved") + } + } } } -} -impl WireFormat for MsgObsDepB { - const MIN_LEN: usize = ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.obs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.obs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgObsDepB { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - obs: WireFormat::parse_unchecked(buf), + impl TryFrom for HalfCycleAmbiguity { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(HalfCycleAmbiguity::HalfCyclePhaseAmbiguityUnresolved), + 1 => Ok(HalfCycleAmbiguity::HalfCyclePhaseAmbiguityResolved), + i => Err(i), + } } } -} -/// Deprecated -/// -/// The GPS observations message reports all the raw pseudorange and carrier -/// phase observations for the satellites being tracked by the device. Carrier -/// phase observation here is represented as a 40-bit fixed point number with -/// Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional -/// cycles). The observations are interoperable with 3rd party receivers and -/// conform with typical RTCMv3 GNSS observations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgObsDepC { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a GPS observation message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: ObservationHeaderDep, - /// Pseudorange and carrier phase observation for a satellite being tracked. - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] - pub obs: Vec, -} - -impl ConcreteMessage for MsgObsDepC { - const MESSAGE_TYPE: u16 = 73; - const MESSAGE_NAME: &'static str = "MSG_OBS_DEP_C"; -} + /// Carrier phase valid + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CarrierPhaseValid { + /// Invalid carrier phase measurement + InvalidCarrierPhaseMeasurement = 0, -impl SbpMessage for MsgObsDepC { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Valid carrier phase measurement + ValidCarrierPhaseMeasurement = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + + impl std::fmt::Display for CarrierPhaseValid { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CarrierPhaseValid::InvalidCarrierPhaseMeasurement => { + f.write_str("Invalid carrier phase measurement") + } + CarrierPhaseValid::ValidCarrierPhaseMeasurement => { + f.write_str("Valid carrier phase measurement") + } + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for CarrierPhaseValid { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CarrierPhaseValid::InvalidCarrierPhaseMeasurement), + 1 => Ok(CarrierPhaseValid::ValidCarrierPhaseMeasurement), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Pseudorange valid + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PseudorangeValid { + /// Invalid pseudorange measurement + InvalidPseudorangeMeasurement = 0, + + /// Valid pseudorange measurement and coarse TOW decoded + ValidPseudorangeMeasurementAndCoarseTowDecoded = 1, } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.header.t.tow as f64) / 1000.0; - let wn: i16 = match self.header.t.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl std::fmt::Display for PseudorangeValid { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PseudorangeValid::InvalidPseudorangeMeasurement => { + f.write_str("Invalid pseudorange measurement") + } + PseudorangeValid::ValidPseudorangeMeasurementAndCoarseTowDecoded => { + f.write_str("Valid pseudorange measurement and coarse TOW decoded") + } + } + } } -} -impl TryFrom for MsgObsDepC { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgObsDepC(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for PseudorangeValid { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PseudorangeValid::InvalidPseudorangeMeasurement), + 1 => Ok(PseudorangeValid::ValidPseudorangeMeasurementAndCoarseTowDecoded), + i => Err(i), + } } } } -impl WireFormat for MsgObsDepC { - const MIN_LEN: usize = ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.obs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.obs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgObsDepC { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - obs: WireFormat::parse_unchecked(buf), +pub mod packed_obs_content_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PackedObsContentDepA { + /// Pseudorange observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Carrier phase observation with opposite sign from typical convention + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhaseDepA, + /// Carrier-to-Noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock indicator. This value changes whenever a satellite signal has lost + /// and regained lock, indicating that the carrier phase ambiguity may have + /// changed. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u16, + /// PRN-1 identifier of the satellite signal + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + } + + impl WireFormat for PackedObsContentDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.p) + + WireFormat::len(&self.l) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.prn) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.p, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.prn, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PackedObsContentDepA { + p: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + } } } } -/// OSR corrections -/// -/// The OSR message contains network corrections in an observation-like -/// format. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgOsr { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a GPS observation message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: ObservationHeader, - /// Network correction for a satellite signal. - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs")))] - pub obs: Vec, -} +pub mod packed_obs_content_dep_b { + #![allow(unused_imports)] -impl ConcreteMessage for MsgOsr { - const MESSAGE_TYPE: u16 = 1600; - const MESSAGE_NAME: &'static str = "MSG_OSR"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgOsr { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.header.t.tow as f64) / 1000.0; - let wn: i16 = match self.header.t.wn.try_into() { - Ok(wn) => wn, - Err(e) => return Some(Err(e.into())), - }; - let gps_time = match time::GpsTime::new(wn, tow_s) { - Ok(gps_time) => gps_time, - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Base(gps_time.into()))) + /// GPS observations for a particular satellite signal + /// + /// Pseudorange and carrier phase observation for a satellite being tracked. + /// Pseudoranges are referenced to a nominal pseudorange. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PackedObsContentDepB { + /// Pseudorange observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Carrier phase observation with opposite sign from typical convention. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhaseDepA, + /// Carrier-to-Noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock indicator. This value changes whenever a satellite signal has lost + /// and regained lock, indicating that the carrier phase ambiguity may have + /// changed. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u16, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + } + + impl WireFormat for PackedObsContentDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.p) + + WireFormat::len(&self.l) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.p, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PackedObsContentDepB { + p: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgOsr { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgOsr(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod packed_obs_content_dep_c { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// GPS observations for a particular satellite signal + /// + /// Pseudorange and carrier phase observation for a satellite being tracked. + /// The observations are be interoperable with 3rd party receivers and conform + /// with typical RTCMv3 GNSS observations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PackedObsContentDepC { + /// Pseudorange observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Carrier phase observation with typical sign convention. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhase, + /// Carrier-to-Noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock indicator. This value changes whenever a satellite signal has lost + /// and regained lock, indicating that the carrier phase ambiguity may have + /// changed. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u16, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + } + + impl WireFormat for PackedObsContentDepC { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.p) + + WireFormat::len(&self.l) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.p, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PackedObsContentDepC { + p: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgOsr { - const MIN_LEN: usize = - ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.obs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.obs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgOsr { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - obs: WireFormat::parse_unchecked(buf), +pub mod packed_osr_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Network correction for a particular satellite signal + /// + /// Pseudorange and carrier phase network corrections for a satellite signal. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PackedOsrContent { + /// Pseudorange observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Carrier phase observation with typical sign convention. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhase, + /// Lock timer. This value gives an indication of the time for which a + /// signal has maintained continuous phase lock. Whenever a signal has lost + /// and regained lock, this value is reset to zero. It is encoded according + /// to DF402 from the RTCM 10403.2 Amendment 2 specification. Valid values + /// range from 0 to 15 and the most significant nibble is reserved for + /// future use. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u8, + /// Correction flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Slant ionospheric correction standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "iono_std")))] + pub iono_std: u16, + /// Slant tropospheric correction standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_std")))] + pub tropo_std: u16, + /// Orbit/clock/bias correction projected on range standard deviation + #[cfg_attr(feature = "serde", serde(rename(serialize = "range_std")))] + pub range_std: u16, + } + + impl PackedOsrContent { + /// Gets the [InvalidPhaseCorrections][self::InvalidPhaseCorrections] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InvalidPhaseCorrections` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InvalidPhaseCorrections` were added. + pub fn invalid_phase_corrections(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 4).try_into() } - } -} -/// Satellite azimuths and elevations -/// -/// Azimuth and elevation angles of all the visible satellites that the device -/// does have ephemeris or almanac for. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSvAzEl { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Azimuth and elevation per satellite - #[cfg_attr(feature = "serde", serde(rename(serialize = "azel")))] - pub azel: Vec, -} + /// Set the bitrange corresponding to the [InvalidPhaseCorrections][InvalidPhaseCorrections] of the `flags` bitfield. + pub fn set_invalid_phase_corrections( + &mut self, + invalid_phase_corrections: InvalidPhaseCorrections, + ) { + set_bit_range!(&mut self.flags, invalid_phase_corrections, u8, u8, 4, 4); + } -impl ConcreteMessage for MsgSvAzEl { - const MESSAGE_TYPE: u16 = 151; - const MESSAGE_NAME: &'static str = "MSG_SV_AZ_EL"; -} + /// Gets the [InvalidCodeCorrections][self::InvalidCodeCorrections] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InvalidCodeCorrections` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InvalidCodeCorrections` were added. + pub fn invalid_code_corrections(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 3).try_into() + } -impl SbpMessage for MsgSvAzEl { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Set the bitrange corresponding to the [InvalidCodeCorrections][InvalidCodeCorrections] of the `flags` bitfield. + pub fn set_invalid_code_corrections( + &mut self, + invalid_code_corrections: InvalidCodeCorrections, + ) { + set_bit_range!(&mut self.flags, invalid_code_corrections, u8, u8, 3, 3); + } -impl TryFrom for MsgSvAzEl { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSvAzEl(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Gets the [FullFixingFlag][self::FullFixingFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FullFixingFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FullFixingFlag` were added. + pub fn full_fixing_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 2).try_into() } - } -} -impl WireFormat for MsgSvAzEl { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.azel) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.azel, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSvAzEl { - sender_id: None, - azel: WireFormat::parse_unchecked(buf), + /// Set the bitrange corresponding to the [FullFixingFlag][FullFixingFlag] of the `flags` bitfield. + pub fn set_full_fixing_flag(&mut self, full_fixing_flag: FullFixingFlag) { + set_bit_range!(&mut self.flags, full_fixing_flag, u8, u8, 2, 2); } - } -} -/// L2C capability mask -/// -/// Please see ICD-GPS-200 (Chapter 20.3.3.5.1.4) for more details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSvConfigurationGpsDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Navigation Message Correction Table Validity Time - #[cfg_attr(feature = "serde", serde(rename(serialize = "t_nmct")))] - pub t_nmct: GpsTimeSec, - /// L2C capability mask, SV32 bit being MSB, SV1 bit being LSB - #[cfg_attr(feature = "serde", serde(rename(serialize = "l2c_mask")))] - pub l2c_mask: u32, -} + /// Gets the [PartialFixingFlag][self::PartialFixingFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PartialFixingFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PartialFixingFlag` were added. + pub fn partial_fixing_flag(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 1).try_into() + } -impl ConcreteMessage for MsgSvConfigurationGpsDep { - const MESSAGE_TYPE: u16 = 145; - const MESSAGE_NAME: &'static str = "MSG_SV_CONFIGURATION_GPS_DEP"; -} + /// Set the bitrange corresponding to the [PartialFixingFlag][PartialFixingFlag] of the `flags` bitfield. + pub fn set_partial_fixing_flag(&mut self, partial_fixing_flag: PartialFixingFlag) { + set_bit_range!(&mut self.flags, partial_fixing_flag, u8, u8, 1, 1); + } -impl SbpMessage for MsgSvConfigurationGpsDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the [CorrectionValidity][self::CorrectionValidity] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CorrectionValidity` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CorrectionValidity` were added. + pub fn correction_validity(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 0, 0).try_into() + } -impl TryFrom for MsgSvConfigurationGpsDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSvConfigurationGpsDep(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Set the bitrange corresponding to the [CorrectionValidity][CorrectionValidity] of the `flags` bitfield. + pub fn set_correction_validity(&mut self, correction_validity: CorrectionValidity) { + set_bit_range!(&mut self.flags, correction_validity, u8, u8, 0, 0); } } -} -impl WireFormat for MsgSvConfigurationGpsDep { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t_nmct) + WireFormat::len(&self.l2c_mask) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t_nmct, buf); - WireFormat::write(&self.l2c_mask, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSvConfigurationGpsDep { - sender_id: None, - t_nmct: WireFormat::parse_unchecked(buf), - l2c_mask: WireFormat::parse_unchecked(buf), + impl WireFormat for PackedOsrContent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.p) + + WireFormat::len(&self.l) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.iono_std) + + WireFormat::len(&self.tropo_std) + + WireFormat::len(&self.range_std) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.p, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.iono_std, buf); + WireFormat::write(&self.tropo_std, buf); + WireFormat::write(&self.range_std, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PackedOsrContent { + p: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + iono_std: WireFormat::parse_unchecked(buf), + tropo_std: WireFormat::parse_unchecked(buf), + range_std: WireFormat::parse_unchecked(buf), + } } } -} -/// Header for observation message -/// -/// Header of a GNSS observation message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct ObservationHeader { - /// GNSS time of this observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: GpsTime, - /// Total number of observations. First nibble is the size of the sequence - /// (n), second nibble is the zero-indexed counter (ith packet of n) - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_obs")))] - pub n_obs: u8, -} + /// Invalid phase corrections + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InvalidPhaseCorrections { + /// Valid phase corrections + ValidPhaseCorrections = 0, -impl WireFormat for ObservationHeader { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t) + WireFormat::len(&self.n_obs) + /// Do not use phase corrections + DoNotUsePhaseCorrections = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t, buf); - WireFormat::write(&self.n_obs, buf); + + impl std::fmt::Display for InvalidPhaseCorrections { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InvalidPhaseCorrections::ValidPhaseCorrections => { + f.write_str("Valid phase corrections") + } + InvalidPhaseCorrections::DoNotUsePhaseCorrections => { + f.write_str("Do not use phase corrections") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - ObservationHeader { - t: WireFormat::parse_unchecked(buf), - n_obs: WireFormat::parse_unchecked(buf), + + impl TryFrom for InvalidPhaseCorrections { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InvalidPhaseCorrections::ValidPhaseCorrections), + 1 => Ok(InvalidPhaseCorrections::DoNotUsePhaseCorrections), + i => Err(i), + } } } -} -/// Header for observation message -/// -/// Header of a GPS observation message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct ObservationHeaderDep { - /// GPS time of this observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: GpsTimeDep, - /// Total number of observations. First nibble is the size of the sequence - /// (n), second nibble is the zero-indexed counter (ith packet of n) - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_obs")))] - pub n_obs: u8, -} + /// Invalid code corrections + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InvalidCodeCorrections { + /// Valid code corrections + ValidCodeCorrections = 0, -impl WireFormat for ObservationHeaderDep { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.t) + WireFormat::len(&self.n_obs) + /// Do not use code corrections + DoNotUseCodeCorrections = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.t, buf); - WireFormat::write(&self.n_obs, buf); + + impl std::fmt::Display for InvalidCodeCorrections { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InvalidCodeCorrections::ValidCodeCorrections => { + f.write_str("Valid code corrections") + } + InvalidCodeCorrections::DoNotUseCodeCorrections => { + f.write_str("Do not use code corrections") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - ObservationHeaderDep { - t: WireFormat::parse_unchecked(buf), - n_obs: WireFormat::parse_unchecked(buf), + + impl TryFrom for InvalidCodeCorrections { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InvalidCodeCorrections::ValidCodeCorrections), + 1 => Ok(InvalidCodeCorrections::DoNotUseCodeCorrections), + i => Err(i), + } } } -} -/// GNSS observations for a particular satellite signal -/// -/// Pseudorange and carrier phase observation for a satellite being tracked. -/// The observations are interoperable with 3rd party receivers and conform -/// with typical RTCM 3.1 message GPS/GLO observations. -/// -/// Carrier phase observations are not guaranteed to be aligned to the RINEX 3 -/// or RTCM 3.3 MSM reference signal and no 1/4 cycle adjustments are -/// currently performed. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PackedObsContent { - /// Pseudorange observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Carrier phase observation with typical sign convention. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhase, - /// Doppler observation with typical sign convention. - #[cfg_attr(feature = "serde", serde(rename(serialize = "D")))] - pub d: Doppler, - /// Carrier-to-Noise density. Zero implies invalid cn0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock timer. This value gives an indication of the time for which a - /// signal has maintained continuous phase lock. Whenever a signal has lost - /// and regained lock, this value is reset to zero. It is encoded according - /// to DF402 from the RTCM 10403.2 Amendment 2 specification. Valid values - /// range from 0 to 15 and the most significant nibble is reserved for - /// future use. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u8, - /// Measurement status flags. A bit field of flags providing the status of - /// this observation. If this field is 0 it means only the Cn0 estimate for - /// the signal is valid. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, -} + /// Full fixing flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FullFixingFlag { + /// Full fixing unavailable + FullFixingUnavailable = 0, -impl WireFormat for PackedObsContent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.p) - + WireFormat::len(&self.l) - + WireFormat::len(&self.d) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.p, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.d, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PackedObsContent { - p: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - d: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - } + /// Full fixing available + FullFixingAvailable = 1, } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PackedObsContentDepA { - /// Pseudorange observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Carrier phase observation with opposite sign from typical convention - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhaseDepA, - /// Carrier-to-Noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock indicator. This value changes whenever a satellite signal has lost - /// and regained lock, indicating that the carrier phase ambiguity may have - /// changed. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u16, - /// PRN-1 identifier of the satellite signal - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, -} + impl std::fmt::Display for FullFixingFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FullFixingFlag::FullFixingUnavailable => f.write_str("Full fixing unavailable"), + FullFixingFlag::FullFixingAvailable => f.write_str("Full fixing available"), + } + } + } -impl WireFormat for PackedObsContentDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.p) - + WireFormat::len(&self.l) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.prn) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.p, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.prn, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PackedObsContentDepA { - p: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), + impl TryFrom for FullFixingFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FullFixingFlag::FullFixingUnavailable), + 1 => Ok(FullFixingFlag::FullFixingAvailable), + i => Err(i), + } } } -} -/// GPS observations for a particular satellite signal -/// -/// Pseudorange and carrier phase observation for a satellite being tracked. -/// Pseudoranges are referenced to a nominal pseudorange. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PackedObsContentDepB { - /// Pseudorange observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Carrier phase observation with opposite sign from typical convention. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhaseDepA, - /// Carrier-to-Noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock indicator. This value changes whenever a satellite signal has lost - /// and regained lock, indicating that the carrier phase ambiguity may have - /// changed. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u16, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, -} + /// Partial fixing flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PartialFixingFlag { + /// Partial fixing unavailable + PartialFixingUnavailable = 0, -impl WireFormat for PackedObsContentDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.p) - + WireFormat::len(&self.l) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.p, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PackedObsContentDepB { - p: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - } + /// Partial fixing available + PartialFixingAvailable = 1, } -} -/// GPS observations for a particular satellite signal -/// -/// Pseudorange and carrier phase observation for a satellite being tracked. -/// The observations are be interoperable with 3rd party receivers and conform -/// with typical RTCMv3 GNSS observations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PackedObsContentDepC { - /// Pseudorange observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Carrier phase observation with typical sign convention. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhase, - /// Carrier-to-Noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock indicator. This value changes whenever a satellite signal has lost - /// and regained lock, indicating that the carrier phase ambiguity may have - /// changed. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u16, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, -} + impl std::fmt::Display for PartialFixingFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PartialFixingFlag::PartialFixingUnavailable => { + f.write_str("Partial fixing unavailable") + } + PartialFixingFlag::PartialFixingAvailable => { + f.write_str("Partial fixing available") + } + } + } + } -impl WireFormat for PackedObsContentDepC { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.p) - + WireFormat::len(&self.l) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.p, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PackedObsContentDepC { - p: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + impl TryFrom for PartialFixingFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PartialFixingFlag::PartialFixingUnavailable), + 1 => Ok(PartialFixingFlag::PartialFixingAvailable), + i => Err(i), + } } } -} -/// Network correction for a particular satellite signal -/// -/// Pseudorange and carrier phase network corrections for a satellite signal. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PackedOsrContent { - /// Pseudorange observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Carrier phase observation with typical sign convention. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhase, - /// Lock timer. This value gives an indication of the time for which a - /// signal has maintained continuous phase lock. Whenever a signal has lost - /// and regained lock, this value is reset to zero. It is encoded according - /// to DF402 from the RTCM 10403.2 Amendment 2 specification. Valid values - /// range from 0 to 15 and the most significant nibble is reserved for - /// future use. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u8, - /// Correction flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Slant ionospheric correction standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "iono_std")))] - pub iono_std: u16, - /// Slant tropospheric correction standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_std")))] - pub tropo_std: u16, - /// Orbit/clock/bias correction projected on range standard deviation - #[cfg_attr(feature = "serde", serde(rename(serialize = "range_std")))] - pub range_std: u16, -} + /// Correction validity + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CorrectionValidity { + /// Do not use signal + DoNotUseSignal = 0, + + /// Valid signal + ValidSignal = 1, + } -impl WireFormat for PackedOsrContent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.p) - + WireFormat::len(&self.l) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.iono_std) - + WireFormat::len(&self.tropo_std) - + WireFormat::len(&self.range_std) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.p, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.iono_std, buf); - WireFormat::write(&self.tropo_std, buf); - WireFormat::write(&self.range_std, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PackedOsrContent { - p: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - iono_std: WireFormat::parse_unchecked(buf), - tropo_std: WireFormat::parse_unchecked(buf), - range_std: WireFormat::parse_unchecked(buf), + impl std::fmt::Display for CorrectionValidity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CorrectionValidity::DoNotUseSignal => f.write_str("Do not use signal"), + CorrectionValidity::ValidSignal => f.write_str("Valid signal"), + } } } -} -/// Satellite azimuth and elevation -/// -/// Satellite azimuth and elevation. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct SvAzEl { - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Azimuth angle (range 0..179) - #[cfg_attr(feature = "serde", serde(rename(serialize = "az")))] - pub az: u8, - /// Elevation angle (range -90..90) - #[cfg_attr(feature = "serde", serde(rename(serialize = "el")))] - pub el: i8, + impl TryFrom for CorrectionValidity { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CorrectionValidity::DoNotUseSignal), + 1 => Ok(CorrectionValidity::ValidSignal), + i => Err(i), + } + } + } } -impl WireFormat for SvAzEl { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) + WireFormat::len(&self.az) + WireFormat::len(&self.el) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.az, buf); - WireFormat::write(&self.el, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - SvAzEl { - sid: WireFormat::parse_unchecked(buf), - az: WireFormat::parse_unchecked(buf), - el: WireFormat::parse_unchecked(buf), +pub mod sv_az_el { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Satellite azimuth and elevation + /// + /// Satellite azimuth and elevation. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct SvAzEl { + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Azimuth angle (range 0..179) + #[cfg_attr(feature = "serde", serde(rename(serialize = "az")))] + pub az: u8, + /// Elevation angle (range -90..90) + #[cfg_attr(feature = "serde", serde(rename(serialize = "el")))] + pub el: i8, + } + + impl WireFormat for SvAzEl { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + WireFormat::len(&self.az) + WireFormat::len(&self.el) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.az, buf); + WireFormat::write(&self.el, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + SvAzEl { + sid: WireFormat::parse_unchecked(buf), + az: WireFormat::parse_unchecked(buf), + el: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/orientation.rs b/rust/sbp/src/messages/orientation.rs index 5b68f0aab5..e4637b71cb 100644 --- a/rust/sbp/src/messages/orientation.rs +++ b/rust/sbp/src/messages/orientation.rs @@ -13,480 +13,704 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Orientation Messages +pub use msg_angular_rate::MsgAngularRate; +pub use msg_baseline_heading::MsgBaselineHeading; +pub use msg_orient_euler::MsgOrientEuler; +pub use msg_orient_quat::MsgOrientQuat; -use super::lib::*; - -/// Vehicle Body Frame instantaneous angular rates -/// -/// This message reports the orientation rates in the vehicle body frame. The -/// values represent the measurements a strapped down gyroscope would make and -/// are not equivalent to the time derivative of the Euler angles. The -/// orientation and origin of the user frame is specified via device settings. -/// By convention, the vehicle x-axis is expected to be aligned with the -/// forward direction, while the vehicle y-axis is expected to be aligned with -/// the right direction, and the vehicle z-axis should be aligned with the -/// down direction. This message will only be available in future INS versions -/// of Swift Products and is not produced by Piksi Multi or Duro. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAngularRate { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// angular rate about x axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// angular rate about y axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// angular rate about z axis - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_angular_rate { + #![allow(unused_imports)] -impl ConcreteMessage for MsgAngularRate { - const MESSAGE_TYPE: u16 = 546; - const MESSAGE_NAME: &'static str = "MSG_ANGULAR_RATE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgAngularRate { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Vehicle Body Frame instantaneous angular rates + /// + /// This message reports the orientation rates in the vehicle body frame. The + /// values represent the measurements a strapped down gyroscope would make and + /// are not equivalent to the time derivative of the Euler angles. The + /// orientation and origin of the user frame is specified via device settings. + /// By convention, the vehicle x-axis is expected to be aligned with the + /// forward direction, while the vehicle y-axis is expected to be aligned with + /// the right direction, and the vehicle z-axis should be aligned with the + /// down direction. This message will only be available in future INS versions + /// of Swift Products and is not produced by Piksi Multi or Duro. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAngularRate { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// angular rate about x axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// angular rate about y axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// angular rate about z axis + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgAngularRate { + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgAngularRate { + const MESSAGE_TYPE: u16 = 546; + const MESSAGE_NAME: &'static str = "MSG_ANGULAR_RATE"; + } + + impl SbpMessage for MsgAngularRate { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgAngularRate { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAngularRate(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgAngularRate { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgAngularRate { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// Invalid + Invalid = 0, + + /// Valid + Valid = 1, } -} -impl TryFrom for MsgAngularRate { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAngularRate(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::Invalid => f.write_str("Invalid"), + InsNavigationMode::Valid => f.write_str("Valid"), + } } } -} -impl WireFormat for MsgAngularRate { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgAngularRate { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::Invalid), + 1 => Ok(InsNavigationMode::Valid), + i => Err(i), + } } } } -/// Heading relative to True North -/// -/// This message reports the baseline heading pointing from the base station -/// to the rover relative to True North. The full GPS time is given by the -/// preceding MSG_GPS_TIME with the matching time-of-week (tow). It is -/// intended that time-matched RTK mode is used when the base station is -/// moving. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgBaselineHeading { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Heading - #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] - pub heading: u32, - /// Number of satellites used in solution - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_baseline_heading { + #![allow(unused_imports)] -impl ConcreteMessage for MsgBaselineHeading { - const MESSAGE_TYPE: u16 = 527; - const MESSAGE_NAME: &'static str = "MSG_BASELINE_HEADING"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgBaselineHeading { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Heading relative to True North + /// + /// This message reports the baseline heading pointing from the base station + /// to the rover relative to True North. The full GPS time is given by the + /// preceding MSG_GPS_TIME with the matching time-of-week (tow). It is + /// intended that time-matched RTK mode is used when the base station is + /// moving. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgBaselineHeading { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Heading + #[cfg_attr(feature = "serde", serde(rename(serialize = "heading")))] + pub heading: u32, + /// Number of satellites used in solution + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgBaselineHeading { + /// Gets the [FixMode][self::FixMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FixMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FixMode` were added. + pub fn fix_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [FixMode][FixMode] of the `flags` bitfield. + pub fn set_fix_mode(&mut self, fix_mode: FixMode) { + set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgBaselineHeading { + const MESSAGE_TYPE: u16 = 527; + const MESSAGE_NAME: &'static str = "MSG_BASELINE_HEADING"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgBaselineHeading { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgBaselineHeading { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgBaselineHeading(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgBaselineHeading { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.heading) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.heading, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgBaselineHeading { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + heading: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// Fix mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FixMode { + /// Invalid + Invalid = 0, + + /// Differential GNSS (DGNSS) + DifferentialGnss = 2, + + /// Float RTK + FloatRtk = 3, + + /// Fixed RTK + FixedRtk = 4, } -} -impl TryFrom for MsgBaselineHeading { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgBaselineHeading(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for FixMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FixMode::Invalid => f.write_str("Invalid"), + FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"), + FixMode::FloatRtk => f.write_str("Float RTK"), + FixMode::FixedRtk => f.write_str("Fixed RTK"), + } } } -} -impl WireFormat for MsgBaselineHeading { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.heading) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.heading, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgBaselineHeading { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - heading: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for FixMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FixMode::Invalid), + 2 => Ok(FixMode::DifferentialGnss), + 3 => Ok(FixMode::FloatRtk), + 4 => Ok(FixMode::FixedRtk), + i => Err(i), + } } } } -/// Euler angles -/// -/// This message reports the yaw, pitch, and roll angles of the vehicle body -/// frame. The rotations should applied intrinsically in the order yaw, pitch, -/// and roll in order to rotate the from a frame aligned with the local-level -/// NED frame to the vehicle body frame. This message will only be available -/// in future INS versions of Swift Products and is not produced by Piksi -/// Multi or Duro. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgOrientEuler { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// rotation about the forward axis of the vehicle - #[cfg_attr(feature = "serde", serde(rename(serialize = "roll")))] - pub roll: i32, - /// rotation about the rightward axis of the vehicle - #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch")))] - pub pitch: i32, - /// rotation about the downward axis of the vehicle - #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw")))] - pub yaw: i32, - /// Estimated standard deviation of roll - #[cfg_attr(feature = "serde", serde(rename(serialize = "roll_accuracy")))] - pub roll_accuracy: f32, - /// Estimated standard deviation of pitch - #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch_accuracy")))] - pub pitch_accuracy: f32, - /// Estimated standard deviation of yaw - #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw_accuracy")))] - pub yaw_accuracy: f32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_orient_euler { + #![allow(unused_imports)] -impl ConcreteMessage for MsgOrientEuler { - const MESSAGE_TYPE: u16 = 545; - const MESSAGE_NAME: &'static str = "MSG_ORIENT_EULER"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgOrientEuler { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Euler angles + /// + /// This message reports the yaw, pitch, and roll angles of the vehicle body + /// frame. The rotations should applied intrinsically in the order yaw, pitch, + /// and roll in order to rotate the from a frame aligned with the local-level + /// NED frame to the vehicle body frame. This message will only be available + /// in future INS versions of Swift Products and is not produced by Piksi + /// Multi or Duro. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgOrientEuler { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// rotation about the forward axis of the vehicle + #[cfg_attr(feature = "serde", serde(rename(serialize = "roll")))] + pub roll: i32, + /// rotation about the rightward axis of the vehicle + #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch")))] + pub pitch: i32, + /// rotation about the downward axis of the vehicle + #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw")))] + pub yaw: i32, + /// Estimated standard deviation of roll + #[cfg_attr(feature = "serde", serde(rename(serialize = "roll_accuracy")))] + pub roll_accuracy: f32, + /// Estimated standard deviation of pitch + #[cfg_attr(feature = "serde", serde(rename(serialize = "pitch_accuracy")))] + pub pitch_accuracy: f32, + /// Estimated standard deviation of yaw + #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw_accuracy")))] + pub yaw_accuracy: f32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgOrientEuler { + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgOrientEuler { + const MESSAGE_TYPE: u16 = 545; + const MESSAGE_NAME: &'static str = "MSG_ORIENT_EULER"; + } + + impl SbpMessage for MsgOrientEuler { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgOrientEuler { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgOrientEuler(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgOrientEuler { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.roll) + + WireFormat::len(&self.pitch) + + WireFormat::len(&self.yaw) + + WireFormat::len(&self.roll_accuracy) + + WireFormat::len(&self.pitch_accuracy) + + WireFormat::len(&self.yaw_accuracy) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.roll, buf); + WireFormat::write(&self.pitch, buf); + WireFormat::write(&self.yaw, buf); + WireFormat::write(&self.roll_accuracy, buf); + WireFormat::write(&self.pitch_accuracy, buf); + WireFormat::write(&self.yaw_accuracy, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgOrientEuler { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + roll: WireFormat::parse_unchecked(buf), + pitch: WireFormat::parse_unchecked(buf), + yaw: WireFormat::parse_unchecked(buf), + roll_accuracy: WireFormat::parse_unchecked(buf), + pitch_accuracy: WireFormat::parse_unchecked(buf), + yaw_accuracy: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// Invalid + Invalid = 0, + + /// Valid + Valid = 1, } -} -impl TryFrom for MsgOrientEuler { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgOrientEuler(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::Invalid => f.write_str("Invalid"), + InsNavigationMode::Valid => f.write_str("Valid"), + } } } -} -impl WireFormat for MsgOrientEuler { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.roll) - + WireFormat::len(&self.pitch) - + WireFormat::len(&self.yaw) - + WireFormat::len(&self.roll_accuracy) - + WireFormat::len(&self.pitch_accuracy) - + WireFormat::len(&self.yaw_accuracy) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.roll, buf); - WireFormat::write(&self.pitch, buf); - WireFormat::write(&self.yaw, buf); - WireFormat::write(&self.roll_accuracy, buf); - WireFormat::write(&self.pitch_accuracy, buf); - WireFormat::write(&self.yaw_accuracy, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgOrientEuler { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - roll: WireFormat::parse_unchecked(buf), - pitch: WireFormat::parse_unchecked(buf), - yaw: WireFormat::parse_unchecked(buf), - roll_accuracy: WireFormat::parse_unchecked(buf), - pitch_accuracy: WireFormat::parse_unchecked(buf), - yaw_accuracy: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::Invalid), + 1 => Ok(InsNavigationMode::Valid), + i => Err(i), + } } } } -/// Quaternion 4 component vector -/// -/// This message reports the quaternion vector describing the vehicle body -/// frame's orientation with respect to a local-level NED frame. The -/// components of the vector should sum to a unit vector assuming that the LSB -/// of each component as a value of 2^-31. This message will only be available -/// in future INS versions of Swift Products and is not produced by Piksi -/// Multi or Duro. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgOrientQuat { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Real component - #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] - pub w: i32, - /// 1st imaginary component - #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] - pub x: i32, - /// 2nd imaginary component - #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] - pub y: i32, - /// 3rd imaginary component - #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] - pub z: i32, - /// Estimated standard deviation of w - #[cfg_attr(feature = "serde", serde(rename(serialize = "w_accuracy")))] - pub w_accuracy: f32, - /// Estimated standard deviation of x - #[cfg_attr(feature = "serde", serde(rename(serialize = "x_accuracy")))] - pub x_accuracy: f32, - /// Estimated standard deviation of y - #[cfg_attr(feature = "serde", serde(rename(serialize = "y_accuracy")))] - pub y_accuracy: f32, - /// Estimated standard deviation of z - #[cfg_attr(feature = "serde", serde(rename(serialize = "z_accuracy")))] - pub z_accuracy: f32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_orient_quat { + #![allow(unused_imports)] -impl ConcreteMessage for MsgOrientQuat { - const MESSAGE_TYPE: u16 = 544; - const MESSAGE_NAME: &'static str = "MSG_ORIENT_QUAT"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgOrientQuat { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Quaternion 4 component vector + /// + /// This message reports the quaternion vector describing the vehicle body + /// frame's orientation with respect to a local-level NED frame. The + /// components of the vector should sum to a unit vector assuming that the LSB + /// of each component as a value of 2^-31. This message will only be available + /// in future INS versions of Swift Products and is not produced by Piksi + /// Multi or Duro. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgOrientQuat { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Real component + #[cfg_attr(feature = "serde", serde(rename(serialize = "w")))] + pub w: i32, + /// 1st imaginary component + #[cfg_attr(feature = "serde", serde(rename(serialize = "x")))] + pub x: i32, + /// 2nd imaginary component + #[cfg_attr(feature = "serde", serde(rename(serialize = "y")))] + pub y: i32, + /// 3rd imaginary component + #[cfg_attr(feature = "serde", serde(rename(serialize = "z")))] + pub z: i32, + /// Estimated standard deviation of w + #[cfg_attr(feature = "serde", serde(rename(serialize = "w_accuracy")))] + pub w_accuracy: f32, + /// Estimated standard deviation of x + #[cfg_attr(feature = "serde", serde(rename(serialize = "x_accuracy")))] + pub x_accuracy: f32, + /// Estimated standard deviation of y + #[cfg_attr(feature = "serde", serde(rename(serialize = "y_accuracy")))] + pub y_accuracy: f32, + /// Estimated standard deviation of z + #[cfg_attr(feature = "serde", serde(rename(serialize = "z_accuracy")))] + pub z_accuracy: f32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgOrientQuat { + /// Gets the [InsNavigationMode][self::InsNavigationMode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsNavigationMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsNavigationMode` were added. + pub fn ins_navigation_mode(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [InsNavigationMode][InsNavigationMode] of the `flags` bitfield. + pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) { + set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgOrientQuat { + const MESSAGE_TYPE: u16 = 544; + const MESSAGE_NAME: &'static str = "MSG_ORIENT_QUAT"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgOrientQuat { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } + } + + impl TryFrom for MsgOrientQuat { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgOrientQuat(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgOrientQuat { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.w) + + WireFormat::len(&self.x) + + WireFormat::len(&self.y) + + WireFormat::len(&self.z) + + WireFormat::len(&self.w_accuracy) + + WireFormat::len(&self.x_accuracy) + + WireFormat::len(&self.y_accuracy) + + WireFormat::len(&self.z_accuracy) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.w, buf); + WireFormat::write(&self.x, buf); + WireFormat::write(&self.y, buf); + WireFormat::write(&self.z, buf); + WireFormat::write(&self.w_accuracy, buf); + WireFormat::write(&self.x_accuracy, buf); + WireFormat::write(&self.y_accuracy, buf); + WireFormat::write(&self.z_accuracy, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgOrientQuat { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + w: WireFormat::parse_unchecked(buf), + x: WireFormat::parse_unchecked(buf), + y: WireFormat::parse_unchecked(buf), + z: WireFormat::parse_unchecked(buf), + w_accuracy: WireFormat::parse_unchecked(buf), + x_accuracy: WireFormat::parse_unchecked(buf), + y_accuracy: WireFormat::parse_unchecked(buf), + z_accuracy: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// INS Navigation mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsNavigationMode { + /// Invalid + Invalid = 0, + + /// Valid + Valid = 1, } -} -impl TryFrom for MsgOrientQuat { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgOrientQuat(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsNavigationMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsNavigationMode::Invalid => f.write_str("Invalid"), + InsNavigationMode::Valid => f.write_str("Valid"), + } } } -} -impl WireFormat for MsgOrientQuat { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.w) - + WireFormat::len(&self.x) - + WireFormat::len(&self.y) - + WireFormat::len(&self.z) - + WireFormat::len(&self.w_accuracy) - + WireFormat::len(&self.x_accuracy) - + WireFormat::len(&self.y_accuracy) - + WireFormat::len(&self.z_accuracy) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.w, buf); - WireFormat::write(&self.x, buf); - WireFormat::write(&self.y, buf); - WireFormat::write(&self.z, buf); - WireFormat::write(&self.w_accuracy, buf); - WireFormat::write(&self.x_accuracy, buf); - WireFormat::write(&self.y_accuracy, buf); - WireFormat::write(&self.z_accuracy, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgOrientQuat { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - w: WireFormat::parse_unchecked(buf), - x: WireFormat::parse_unchecked(buf), - y: WireFormat::parse_unchecked(buf), - z: WireFormat::parse_unchecked(buf), - w_accuracy: WireFormat::parse_unchecked(buf), - x_accuracy: WireFormat::parse_unchecked(buf), - y_accuracy: WireFormat::parse_unchecked(buf), - z_accuracy: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for InsNavigationMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsNavigationMode::Invalid), + 1 => Ok(InsNavigationMode::Valid), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/piksi.rs b/rust/sbp/src/messages/piksi.rs index d900505d13..b4294f4ea5 100644 --- a/rust/sbp/src/messages/piksi.rs +++ b/rust/sbp/src/messages/piksi.rs @@ -15,2082 +15,2835 @@ //! System health, configuration, and diagnostic messages specific to the //! Piksi L1 receiver, including a variety of legacy messages that may no //! longer be used. - -use super::gnss::*; - -use super::lib::*; - -/// Receiver-to-base station latency -/// -/// Statistics on the latency of observations received from the base station. -/// As observation packets are received their GPS time is compared to the -/// current GPS time calculated locally by the receiver to give a precise -/// measurement of the end-to-end communication latency in the system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct Latency { - /// Average latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "avg")))] - pub avg: i32, - /// Minimum latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "lmin")))] - pub lmin: i32, - /// Maximum latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "lmax")))] - pub lmax: i32, - /// Smoothed estimate of the current latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "current")))] - pub current: i32, -} - -impl WireFormat for Latency { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.avg) - + WireFormat::len(&self.lmin) - + WireFormat::len(&self.lmax) - + WireFormat::len(&self.current) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.avg, buf); - WireFormat::write(&self.lmin, buf); - WireFormat::write(&self.lmax, buf); - WireFormat::write(&self.current, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - Latency { - avg: WireFormat::parse_unchecked(buf), - lmin: WireFormat::parse_unchecked(buf), - lmax: WireFormat::parse_unchecked(buf), - current: WireFormat::parse_unchecked(buf), +pub use latency::Latency; +pub use msg_almanac::MsgAlmanac; +pub use msg_cell_modem_status::MsgCellModemStatus; +pub use msg_command_output::MsgCommandOutput; +pub use msg_command_req::MsgCommandReq; +pub use msg_command_resp::MsgCommandResp; +pub use msg_cw_results::MsgCwResults; +pub use msg_cw_start::MsgCwStart; +pub use msg_device_monitor::MsgDeviceMonitor; +pub use msg_front_end_gain::MsgFrontEndGain; +pub use msg_iar_state::MsgIarState; +pub use msg_init_base_dep::MsgInitBaseDep; +pub use msg_mask_satellite::MsgMaskSatellite; +pub use msg_mask_satellite_dep::MsgMaskSatelliteDep; +pub use msg_network_bandwidth_usage::MsgNetworkBandwidthUsage; +pub use msg_network_state_req::MsgNetworkStateReq; +pub use msg_network_state_resp::MsgNetworkStateResp; +pub use msg_reset::MsgReset; +pub use msg_reset_dep::MsgResetDep; +pub use msg_reset_filters::MsgResetFilters; +pub use msg_set_time::MsgSetTime; +pub use msg_specan::MsgSpecan; +pub use msg_specan_dep::MsgSpecanDep; +pub use msg_thread_state::MsgThreadState; +pub use msg_uart_state::MsgUartState; +pub use msg_uart_state_depa::MsgUartStateDepa; +pub use network_usage::NetworkUsage; +pub use period::Period; +pub use uart_channel::UARTChannel; + +pub mod latency { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Receiver-to-base station latency + /// + /// Statistics on the latency of observations received from the base station. + /// As observation packets are received their GPS time is compared to the + /// current GPS time calculated locally by the receiver to give a precise + /// measurement of the end-to-end communication latency in the system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct Latency { + /// Average latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "avg")))] + pub avg: i32, + /// Minimum latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "lmin")))] + pub lmin: i32, + /// Maximum latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "lmax")))] + pub lmax: i32, + /// Smoothed estimate of the current latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "current")))] + pub current: i32, + } + + impl WireFormat for Latency { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.avg) + + WireFormat::len(&self.lmin) + + WireFormat::len(&self.lmax) + + WireFormat::len(&self.current) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.avg, buf); + WireFormat::write(&self.lmin, buf); + WireFormat::write(&self.lmax, buf); + WireFormat::write(&self.current, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + Latency { + avg: WireFormat::parse_unchecked(buf), + lmin: WireFormat::parse_unchecked(buf), + lmax: WireFormat::parse_unchecked(buf), + current: WireFormat::parse_unchecked(buf), + } } } } -/// Legacy message to load satellite almanac (host => Piksi) -/// -/// This is a legacy message for sending and loading a satellite alamanac onto -/// the Piksi's flash memory from the host. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgAlmanac { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_almanac { + #![allow(unused_imports)] -impl ConcreteMessage for MsgAlmanac { - const MESSAGE_TYPE: u16 = 105; - const MESSAGE_NAME: &'static str = "MSG_ALMANAC"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgAlmanac { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Legacy message to load satellite almanac (host => Piksi) + /// + /// This is a legacy message for sending and loading a satellite alamanac onto + /// the Piksi's flash memory from the host. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgAlmanac { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgAlmanac { + const MESSAGE_TYPE: u16 = 105; + const MESSAGE_NAME: &'static str = "MSG_ALMANAC"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgAlmanac { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgAlmanac { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgAlmanac(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgAlmanac { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgAlmanac { sender_id: None } + } } } -impl TryFrom for MsgAlmanac { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgAlmanac(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_cell_modem_status { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Cell modem information update message + /// + /// If a cell modem is present on a piksi device, this message will be send + /// periodically to update the host on the status of the modem and its various + /// parameters. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCellModemStatus { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Received cell signal strength in dBm, zero translates to unknown + #[cfg_attr(feature = "serde", serde(rename(serialize = "signal_strength")))] + pub signal_strength: i8, + /// BER as reported by the modem, zero translates to unknown + #[cfg_attr(feature = "serde", serde(rename(serialize = "signal_error_rate")))] + pub signal_error_rate: f32, + /// Unspecified data TBD for this schema + #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] + pub reserved: Vec, + } + + impl ConcreteMessage for MsgCellModemStatus { + const MESSAGE_TYPE: u16 = 190; + const MESSAGE_NAME: &'static str = "MSG_CELL_MODEM_STATUS"; + } + + impl SbpMessage for MsgCellModemStatus { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgAlmanac { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgCellModemStatus { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCellModemStatus(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgAlmanac { sender_id: None } + + impl WireFormat for MsgCellModemStatus { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.signal_strength) + + WireFormat::len(&self.signal_error_rate) + + WireFormat::len(&self.reserved) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.signal_strength, buf); + WireFormat::write(&self.signal_error_rate, buf); + WireFormat::write(&self.reserved, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCellModemStatus { + sender_id: None, + signal_strength: WireFormat::parse_unchecked(buf), + signal_error_rate: WireFormat::parse_unchecked(buf), + reserved: WireFormat::parse_unchecked(buf), + } + } } } -/// Cell modem information update message -/// -/// If a cell modem is present on a piksi device, this message will be send -/// periodically to update the host on the status of the modem and its various -/// parameters. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCellModemStatus { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Received cell signal strength in dBm, zero translates to unknown - #[cfg_attr(feature = "serde", serde(rename(serialize = "signal_strength")))] - pub signal_strength: i8, - /// BER as reported by the modem, zero translates to unknown - #[cfg_attr(feature = "serde", serde(rename(serialize = "signal_error_rate")))] - pub signal_error_rate: f32, - /// Unspecified data TBD for this schema - #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] - pub reserved: Vec, -} +pub mod msg_command_output { + #![allow(unused_imports)] -impl ConcreteMessage for MsgCellModemStatus { - const MESSAGE_TYPE: u16 = 190; - const MESSAGE_NAME: &'static str = "MSG_CELL_MODEM_STATUS"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgCellModemStatus { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Command output + /// + /// Returns the standard output and standard error of the command requested by + /// MSG_COMMAND_REQ. The sequence number can be used to filter for filtering + /// the correct command. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCommandOutput { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Line of standard output or standard error + #[cfg_attr(feature = "serde", serde(rename(serialize = "line")))] + pub line: SbpString, Unterminated>, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgCommandOutput { + const MESSAGE_TYPE: u16 = 188; + const MESSAGE_NAME: &'static str = "MSG_COMMAND_OUTPUT"; } -} -impl TryFrom for MsgCellModemStatus { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCellModemStatus(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgCommandOutput { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCellModemStatus { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.signal_strength) - + WireFormat::len(&self.signal_error_rate) - + WireFormat::len(&self.reserved) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.signal_strength, buf); - WireFormat::write(&self.signal_error_rate, buf); - WireFormat::write(&self.reserved, buf); + impl TryFrom for MsgCommandOutput { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCommandOutput(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCellModemStatus { - sender_id: None, - signal_strength: WireFormat::parse_unchecked(buf), - signal_error_rate: WireFormat::parse_unchecked(buf), - reserved: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgCommandOutput { + const MIN_LEN: usize = ::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + WireFormat::len(&self.line) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.line, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCommandOutput { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + line: WireFormat::parse_unchecked(buf), + } } } } -/// Command output -/// -/// Returns the standard output and standard error of the command requested by -/// MSG_COMMAND_REQ. The sequence number can be used to filter for filtering -/// the correct command. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCommandOutput { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Line of standard output or standard error - #[cfg_attr(feature = "serde", serde(rename(serialize = "line")))] - pub line: SbpString, Unterminated>, -} +pub mod msg_command_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgCommandOutput { - const MESSAGE_TYPE: u16 = 188; - const MESSAGE_NAME: &'static str = "MSG_COMMAND_OUTPUT"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgCommandOutput { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Execute a command (host => device) + /// + /// Request the recipient to execute an command. Output will be sent in + /// MSG_LOG messages, and the exit code will be returned with + /// MSG_COMMAND_RESP. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCommandReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Command line to execute + #[cfg_attr(feature = "serde", serde(rename(serialize = "command")))] + pub command: SbpString, NullTerminated>, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgCommandReq { + const MESSAGE_TYPE: u16 = 184; + const MESSAGE_NAME: &'static str = "MSG_COMMAND_REQ"; } -} -impl TryFrom for MsgCommandOutput { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCommandOutput(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgCommandReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCommandOutput { - const MIN_LEN: usize = - ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) + WireFormat::len(&self.line) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.line, buf); + impl TryFrom for MsgCommandReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCommandReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCommandOutput { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - line: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgCommandReq { + const MIN_LEN: usize = ::MIN_LEN + + , NullTerminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + WireFormat::len(&self.command) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.command, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCommandReq { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + command: WireFormat::parse_unchecked(buf), + } } } } -/// Execute a command (host => device) -/// -/// Request the recipient to execute an command. Output will be sent in -/// MSG_LOG messages, and the exit code will be returned with -/// MSG_COMMAND_RESP. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCommandReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Command line to execute - #[cfg_attr(feature = "serde", serde(rename(serialize = "command")))] - pub command: SbpString, NullTerminated>, -} +pub mod msg_command_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgCommandReq { - const MESSAGE_TYPE: u16 = 184; - const MESSAGE_NAME: &'static str = "MSG_COMMAND_REQ"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgCommandReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Exit code from executed command (device => host) + /// + /// The response to MSG_COMMAND_REQ with the return code of the command. A + /// return code of zero indicates success. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCommandResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Sequence number + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Exit code + #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] + pub code: i32, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgCommandResp { + const MESSAGE_TYPE: u16 = 185; + const MESSAGE_NAME: &'static str = "MSG_COMMAND_RESP"; } -} -impl TryFrom for MsgCommandReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCommandReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgCommandResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCommandReq { - const MIN_LEN: usize = - ::MIN_LEN + , NullTerminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) + WireFormat::len(&self.command) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.command, buf); + impl TryFrom for MsgCommandResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCommandResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCommandReq { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - command: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgCommandResp { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sequence) + WireFormat::len(&self.code) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.code, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCommandResp { + sender_id: None, + sequence: WireFormat::parse_unchecked(buf), + code: WireFormat::parse_unchecked(buf), + } } } } -/// Exit code from executed command (device => host) -/// -/// The response to MSG_COMMAND_REQ with the return code of the command. A -/// return code of zero indicates success. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCommandResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Sequence number - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Exit code - #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] - pub code: i32, -} +pub mod msg_cw_results { + #![allow(unused_imports)] -impl ConcreteMessage for MsgCommandResp { - const MESSAGE_TYPE: u16 = 185; - const MESSAGE_NAME: &'static str = "MSG_COMMAND_RESP"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgCommandResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Legacy message for CW interference channel (Piksi => host) + /// + /// This is an unused legacy message for result reporting from the CW + /// interference channel on the SwiftNAP. This message will be removed in a + /// future release. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCwResults { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgCwResults { + const MESSAGE_TYPE: u16 = 192; + const MESSAGE_NAME: &'static str = "MSG_CW_RESULTS"; } -} -impl TryFrom for MsgCommandResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCommandResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgCwResults { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCommandResp { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sequence) + WireFormat::len(&self.code) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.code, buf); + impl TryFrom for MsgCwResults { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCwResults(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCommandResp { - sender_id: None, - sequence: WireFormat::parse_unchecked(buf), - code: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgCwResults { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgCwResults { sender_id: None } } } } -/// Legacy message for CW interference channel (Piksi => host) -/// -/// This is an unused legacy message for result reporting from the CW -/// interference channel on the SwiftNAP. This message will be removed in a -/// future release. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCwResults { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_cw_start { + #![allow(unused_imports)] -impl ConcreteMessage for MsgCwResults { - const MESSAGE_TYPE: u16 = 192; - const MESSAGE_NAME: &'static str = "MSG_CW_RESULTS"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgCwResults { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Legacy message for CW interference channel (host => Piksi) + /// + /// This is an unused legacy message from the host for starting the CW + /// interference channel on the SwiftNAP. This message will be removed in a + /// future release. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCwStart { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgCwStart { + const MESSAGE_TYPE: u16 = 193; + const MESSAGE_NAME: &'static str = "MSG_CW_START"; } -} -impl TryFrom for MsgCwResults { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCwResults(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgCwStart { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCwResults { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 - } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgCwResults { sender_id: None } + impl TryFrom for MsgCwStart { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCwStart(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} - -/// Legacy message for CW interference channel (host => Piksi) -/// -/// This is an unused legacy message from the host for starting the CW -/// interference channel on the SwiftNAP. This message will be removed in a -/// future release. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCwStart { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} -impl ConcreteMessage for MsgCwStart { - const MESSAGE_TYPE: u16 = 193; - const MESSAGE_NAME: &'static str = "MSG_CW_START"; + impl WireFormat for MsgCwStart { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgCwStart { sender_id: None } + } + } } -impl SbpMessage for MsgCwStart { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id +pub mod msg_device_monitor { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Device temperature and voltage levels + /// + /// This message contains temperature and voltage level measurements from the + /// processor's monitoring system and the RF frontend die temperature if + /// available. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgDeviceMonitor { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Device V_in + #[cfg_attr(feature = "serde", serde(rename(serialize = "dev_vin")))] + pub dev_vin: i16, + /// Processor V_int + #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_vint")))] + pub cpu_vint: i16, + /// Processor V_aux + #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_vaux")))] + pub cpu_vaux: i16, + /// Processor temperature + #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_temperature")))] + pub cpu_temperature: i16, + /// Frontend temperature (if available) + #[cfg_attr(feature = "serde", serde(rename(serialize = "fe_temperature")))] + pub fe_temperature: i16, + } + + impl ConcreteMessage for MsgDeviceMonitor { + const MESSAGE_TYPE: u16 = 181; + const MESSAGE_NAME: &'static str = "MSG_DEVICE_MONITOR"; + } + + impl SbpMessage for MsgDeviceMonitor { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgDeviceMonitor { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgDeviceMonitor(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgDeviceMonitor { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.dev_vin) + + WireFormat::len(&self.cpu_vint) + + WireFormat::len(&self.cpu_vaux) + + WireFormat::len(&self.cpu_temperature) + + WireFormat::len(&self.fe_temperature) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.dev_vin, buf); + WireFormat::write(&self.cpu_vint, buf); + WireFormat::write(&self.cpu_vaux, buf); + WireFormat::write(&self.cpu_temperature, buf); + WireFormat::write(&self.fe_temperature, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgDeviceMonitor { + sender_id: None, + dev_vin: WireFormat::parse_unchecked(buf), + cpu_vint: WireFormat::parse_unchecked(buf), + cpu_vaux: WireFormat::parse_unchecked(buf), + cpu_temperature: WireFormat::parse_unchecked(buf), + fe_temperature: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgCwStart { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCwStart(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_front_end_gain { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// RF AGC status + /// + /// This message describes the gain of each channel in the receiver frontend. + /// Each gain is encoded as a non-dimensional percentage relative to the + /// maximum range possible for the gain stage of the frontend. By convention, + /// each gain array has 8 entries and the index of the array corresponding to + /// the index of the rf channel in the frontend. A gain of 127 percent encodes + /// that rf channel is not present in the hardware. A negative value implies + /// an error for the particular gain stage as reported by the frontend. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgFrontEndGain { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// RF gain for each frontend channel + #[cfg_attr(feature = "serde", serde(rename(serialize = "rf_gain")))] + pub rf_gain: [i8; 8], + /// Intermediate frequency gain for each frontend channel + #[cfg_attr(feature = "serde", serde(rename(serialize = "if_gain")))] + pub if_gain: [i8; 8], + } + + impl ConcreteMessage for MsgFrontEndGain { + const MESSAGE_TYPE: u16 = 191; + const MESSAGE_NAME: &'static str = "MSG_FRONT_END_GAIN"; + } + + impl SbpMessage for MsgFrontEndGain { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgCwStart { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgFrontEndGain { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgFrontEndGain(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgCwStart { sender_id: None } + + impl WireFormat for MsgFrontEndGain { + const MIN_LEN: usize = <[i8; 8] as WireFormat>::MIN_LEN + <[i8; 8] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.rf_gain) + WireFormat::len(&self.if_gain) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.rf_gain, buf); + WireFormat::write(&self.if_gain, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgFrontEndGain { + sender_id: None, + rf_gain: WireFormat::parse_unchecked(buf), + if_gain: WireFormat::parse_unchecked(buf), + } + } } } -/// Device temperature and voltage levels -/// -/// This message contains temperature and voltage level measurements from the -/// processor's monitoring system and the RF frontend die temperature if -/// available. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgDeviceMonitor { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Device V_in - #[cfg_attr(feature = "serde", serde(rename(serialize = "dev_vin")))] - pub dev_vin: i16, - /// Processor V_int - #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_vint")))] - pub cpu_vint: i16, - /// Processor V_aux - #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_vaux")))] - pub cpu_vaux: i16, - /// Processor temperature - #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu_temperature")))] - pub cpu_temperature: i16, - /// Frontend temperature (if available) - #[cfg_attr(feature = "serde", serde(rename(serialize = "fe_temperature")))] - pub fe_temperature: i16, -} +pub mod msg_iar_state { + #![allow(unused_imports)] -impl ConcreteMessage for MsgDeviceMonitor { - const MESSAGE_TYPE: u16 = 181; - const MESSAGE_NAME: &'static str = "MSG_DEVICE_MONITOR"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgDeviceMonitor { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// State of the Integer Ambiguity Resolution (IAR) process + /// + /// This message reports the state of the Integer Ambiguity Resolution (IAR) + /// process, which resolves unknown integer ambiguities from double- + /// differenced carrier-phase measurements from satellite observations. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgIarState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Number of integer ambiguity hypotheses remaining + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_hyps")))] + pub num_hyps: u32, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgIarState { + const MESSAGE_TYPE: u16 = 25; + const MESSAGE_NAME: &'static str = "MSG_IAR_STATE"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgIarState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgDeviceMonitor { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgDeviceMonitor(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgIarState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgIarState(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgDeviceMonitor { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.dev_vin) - + WireFormat::len(&self.cpu_vint) - + WireFormat::len(&self.cpu_vaux) - + WireFormat::len(&self.cpu_temperature) - + WireFormat::len(&self.fe_temperature) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.dev_vin, buf); - WireFormat::write(&self.cpu_vint, buf); - WireFormat::write(&self.cpu_vaux, buf); - WireFormat::write(&self.cpu_temperature, buf); - WireFormat::write(&self.fe_temperature, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgDeviceMonitor { - sender_id: None, - dev_vin: WireFormat::parse_unchecked(buf), - cpu_vint: WireFormat::parse_unchecked(buf), - cpu_vaux: WireFormat::parse_unchecked(buf), - cpu_temperature: WireFormat::parse_unchecked(buf), - fe_temperature: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgIarState { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.num_hyps) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.num_hyps, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgIarState { + sender_id: None, + num_hyps: WireFormat::parse_unchecked(buf), + } } } } -/// RF AGC status -/// -/// This message describes the gain of each channel in the receiver frontend. -/// Each gain is encoded as a non-dimensional percentage relative to the -/// maximum range possible for the gain stage of the frontend. By convention, -/// each gain array has 8 entries and the index of the array corresponding to -/// the index of the rf channel in the frontend. A gain of 127 percent encodes -/// that rf channel is not present in the hardware. A negative value implies -/// an error for the particular gain stage as reported by the frontend. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgFrontEndGain { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// RF gain for each frontend channel - #[cfg_attr(feature = "serde", serde(rename(serialize = "rf_gain")))] - pub rf_gain: [i8; 8], - /// Intermediate frequency gain for each frontend channel - #[cfg_attr(feature = "serde", serde(rename(serialize = "if_gain")))] - pub if_gain: [i8; 8], -} +pub mod msg_init_base_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgFrontEndGain { - const MESSAGE_TYPE: u16 = 191; - const MESSAGE_NAME: &'static str = "MSG_FRONT_END_GAIN"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgFrontEndGain { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Deprecated + /// + /// Deprecated + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgInitBaseDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgInitBaseDep { + const MESSAGE_TYPE: u16 = 35; + const MESSAGE_NAME: &'static str = "MSG_INIT_BASE_DEP"; } -} -impl TryFrom for MsgFrontEndGain { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgFrontEndGain(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgInitBaseDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgFrontEndGain { - const MIN_LEN: usize = <[i8; 8] as WireFormat>::MIN_LEN + <[i8; 8] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.rf_gain) + WireFormat::len(&self.if_gain) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.rf_gain, buf); - WireFormat::write(&self.if_gain, buf); + impl TryFrom for MsgInitBaseDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgInitBaseDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgFrontEndGain { - sender_id: None, - rf_gain: WireFormat::parse_unchecked(buf), - if_gain: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgInitBaseDep { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgInitBaseDep { sender_id: None } } } } -/// State of the Integer Ambiguity Resolution (IAR) process -/// -/// This message reports the state of the Integer Ambiguity Resolution (IAR) -/// process, which resolves unknown integer ambiguities from double- -/// differenced carrier-phase measurements from satellite observations. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgIarState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Number of integer ambiguity hypotheses remaining - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_hyps")))] - pub num_hyps: u32, -} +pub mod msg_mask_satellite { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Mask a satellite from use in Piksi subsystems + /// + /// This message allows setting a mask to prevent a particular satellite from + /// being used in various Piksi subsystems. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgMaskSatellite { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Mask of systems that should ignore this satellite. + #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] + pub mask: u8, + /// GNSS signal for which the mask is applied + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + } + + impl MsgMaskSatellite { + /// Gets the [TrackingChannels][self::TrackingChannels] stored in the `mask` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingChannels` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingChannels` were added. + pub fn tracking_channels(&self) -> Result { + get_bit_range!(self.mask, u8, u8, 1, 1).try_into() + } -impl ConcreteMessage for MsgIarState { - const MESSAGE_TYPE: u16 = 25; - const MESSAGE_NAME: &'static str = "MSG_IAR_STATE"; -} + /// Set the bitrange corresponding to the [TrackingChannels][TrackingChannels] of the `mask` bitfield. + pub fn set_tracking_channels(&mut self, tracking_channels: TrackingChannels) { + set_bit_range!(&mut self.mask, tracking_channels, u8, u8, 1, 1); + } -impl SbpMessage for MsgIarState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the [AcquisitionChannel][self::AcquisitionChannel] stored in the `mask` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AcquisitionChannel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AcquisitionChannel` were added. + pub fn acquisition_channel(&self) -> Result { + get_bit_range!(self.mask, u8, u8, 0, 0).try_into() + } -impl TryFrom for MsgIarState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgIarState(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Set the bitrange corresponding to the [AcquisitionChannel][AcquisitionChannel] of the `mask` bitfield. + pub fn set_acquisition_channel(&mut self, acquisition_channel: AcquisitionChannel) { + set_bit_range!(&mut self.mask, acquisition_channel, u8, u8, 0, 0); } } -} -impl WireFormat for MsgIarState { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.num_hyps) + impl ConcreteMessage for MsgMaskSatellite { + const MESSAGE_TYPE: u16 = 43; + const MESSAGE_NAME: &'static str = "MSG_MASK_SATELLITE"; } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.num_hyps, buf); + + impl SbpMessage for MsgMaskSatellite { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgIarState { - sender_id: None, - num_hyps: WireFormat::parse_unchecked(buf), + + impl TryFrom for MsgMaskSatellite { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgMaskSatellite(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Deprecated -/// -/// Deprecated -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgInitBaseDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} + impl WireFormat for MsgMaskSatellite { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mask) + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mask, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgMaskSatellite { + sender_id: None, + mask: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgInitBaseDep { - const MESSAGE_TYPE: u16 = 35; - const MESSAGE_NAME: &'static str = "MSG_INIT_BASE_DEP"; -} + /// Tracking channels + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingChannels { + /// Enabled + Enabled = 0, -impl SbpMessage for MsgInitBaseDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Drop this PRN if currently tracking + DropThisPrnIfCurrentlyTracking = 1, } -} -impl TryFrom for MsgInitBaseDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgInitBaseDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for TrackingChannels { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingChannels::Enabled => f.write_str("Enabled"), + TrackingChannels::DropThisPrnIfCurrentlyTracking => { + f.write_str("Drop this PRN if currently tracking") + } + } } } -} -impl WireFormat for MsgInitBaseDep { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 - } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgInitBaseDep { sender_id: None } + impl TryFrom for TrackingChannels { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingChannels::Enabled), + 1 => Ok(TrackingChannels::DropThisPrnIfCurrentlyTracking), + i => Err(i), + } + } } -} - -/// Mask a satellite from use in Piksi subsystems -/// -/// This message allows setting a mask to prevent a particular satellite from -/// being used in various Piksi subsystems. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgMaskSatellite { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Mask of systems that should ignore this satellite. - #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] - pub mask: u8, - /// GNSS signal for which the mask is applied - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, -} -impl ConcreteMessage for MsgMaskSatellite { - const MESSAGE_TYPE: u16 = 43; - const MESSAGE_NAME: &'static str = "MSG_MASK_SATELLITE"; -} + /// Acquisition channel + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AcquisitionChannel { + /// Enabled + Enabled = 0, -impl SbpMessage for MsgMaskSatellite { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Skip this satellite on future acquisitions + SkipThisSatelliteOnFutureAcquisitions = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} -impl TryFrom for MsgMaskSatellite { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgMaskSatellite(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for AcquisitionChannel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AcquisitionChannel::Enabled => f.write_str("Enabled"), + AcquisitionChannel::SkipThisSatelliteOnFutureAcquisitions => { + f.write_str("Skip this satellite on future acquisitions") + } + } } } -} -impl WireFormat for MsgMaskSatellite { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mask) + WireFormat::len(&self.sid) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mask, buf); - WireFormat::write(&self.sid, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgMaskSatellite { - sender_id: None, - mask: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + impl TryFrom for AcquisitionChannel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AcquisitionChannel::Enabled), + 1 => Ok(AcquisitionChannel::SkipThisSatelliteOnFutureAcquisitions), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgMaskSatelliteDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Mask of systems that should ignore this satellite. - #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] - pub mask: u8, - /// GNSS signal for which the mask is applied - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, -} +pub mod msg_mask_satellite_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgMaskSatelliteDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Mask of systems that should ignore this satellite. + #[cfg_attr(feature = "serde", serde(rename(serialize = "mask")))] + pub mask: u8, + /// GNSS signal for which the mask is applied + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + } + + impl MsgMaskSatelliteDep { + /// Gets the [TrackingChannels][self::TrackingChannels] stored in the `mask` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingChannels` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingChannels` were added. + pub fn tracking_channels(&self) -> Result { + get_bit_range!(self.mask, u8, u8, 1, 1).try_into() + } -impl ConcreteMessage for MsgMaskSatelliteDep { - const MESSAGE_TYPE: u16 = 27; - const MESSAGE_NAME: &'static str = "MSG_MASK_SATELLITE_DEP"; -} + /// Set the bitrange corresponding to the [TrackingChannels][TrackingChannels] of the `mask` bitfield. + pub fn set_tracking_channels(&mut self, tracking_channels: TrackingChannels) { + set_bit_range!(&mut self.mask, tracking_channels, u8, u8, 1, 1); + } -impl SbpMessage for MsgMaskSatelliteDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the [AcquisitionChannel][self::AcquisitionChannel] stored in the `mask` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AcquisitionChannel` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AcquisitionChannel` were added. + pub fn acquisition_channel(&self) -> Result { + get_bit_range!(self.mask, u8, u8, 0, 0).try_into() + } -impl TryFrom for MsgMaskSatelliteDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgMaskSatelliteDep(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Set the bitrange corresponding to the [AcquisitionChannel][AcquisitionChannel] of the `mask` bitfield. + pub fn set_acquisition_channel(&mut self, acquisition_channel: AcquisitionChannel) { + set_bit_range!(&mut self.mask, acquisition_channel, u8, u8, 0, 0); } } -} -impl WireFormat for MsgMaskSatelliteDep { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mask) + WireFormat::len(&self.sid) + impl ConcreteMessage for MsgMaskSatelliteDep { + const MESSAGE_TYPE: u16 = 27; + const MESSAGE_NAME: &'static str = "MSG_MASK_SATELLITE_DEP"; } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mask, buf); - WireFormat::write(&self.sid, buf); + + impl SbpMessage for MsgMaskSatelliteDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgMaskSatelliteDep { - sender_id: None, - mask: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), + + impl TryFrom for MsgMaskSatelliteDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgMaskSatelliteDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Bandwidth usage reporting message -/// -/// The bandwidth usage, a list of usage by interface. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNetworkBandwidthUsage { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Usage measurement array - #[cfg_attr(feature = "serde", serde(rename(serialize = "interfaces")))] - pub interfaces: Vec, -} + impl WireFormat for MsgMaskSatelliteDep { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mask) + WireFormat::len(&self.sid) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mask, buf); + WireFormat::write(&self.sid, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgMaskSatelliteDep { + sender_id: None, + mask: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgNetworkBandwidthUsage { - const MESSAGE_TYPE: u16 = 189; - const MESSAGE_NAME: &'static str = "MSG_NETWORK_BANDWIDTH_USAGE"; -} + /// Tracking channels + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingChannels { + /// Enabled + Enabled = 0, -impl SbpMessage for MsgNetworkBandwidthUsage { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Drop this PRN if currently tracking + DropThisPrnIfCurrentlyTracking = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for TrackingChannels { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingChannels::Enabled => f.write_str("Enabled"), + TrackingChannels::DropThisPrnIfCurrentlyTracking => { + f.write_str("Drop this PRN if currently tracking") + } + } + } } -} -impl TryFrom for MsgNetworkBandwidthUsage { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNetworkBandwidthUsage(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for TrackingChannels { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingChannels::Enabled), + 1 => Ok(TrackingChannels::DropThisPrnIfCurrentlyTracking), + i => Err(i), + } } } -} -impl WireFormat for MsgNetworkBandwidthUsage { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.interfaces) + /// Acquisition channel + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AcquisitionChannel { + /// Enabled + Enabled = 0, + + /// Skip this satellite on future acquisitions + SkipThisSatelliteOnFutureAcquisitions = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.interfaces, buf); + + impl std::fmt::Display for AcquisitionChannel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AcquisitionChannel::Enabled => f.write_str("Enabled"), + AcquisitionChannel::SkipThisSatelliteOnFutureAcquisitions => { + f.write_str("Skip this satellite on future acquisitions") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgNetworkBandwidthUsage { - sender_id: None, - interfaces: WireFormat::parse_unchecked(buf), + + impl TryFrom for AcquisitionChannel { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AcquisitionChannel::Enabled), + 1 => Ok(AcquisitionChannel::SkipThisSatelliteOnFutureAcquisitions), + i => Err(i), + } } } } -/// Request state of Piksi network interfaces -/// -/// Request state of Piksi network interfaces. Output will be sent in -/// MSG_NETWORK_STATE_RESP messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNetworkStateReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_network_bandwidth_usage { + #![allow(unused_imports)] -impl ConcreteMessage for MsgNetworkStateReq { - const MESSAGE_TYPE: u16 = 186; - const MESSAGE_NAME: &'static str = "MSG_NETWORK_STATE_REQ"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgNetworkStateReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Bandwidth usage reporting message + /// + /// The bandwidth usage, a list of usage by interface. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNetworkBandwidthUsage { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Usage measurement array + #[cfg_attr(feature = "serde", serde(rename(serialize = "interfaces")))] + pub interfaces: Vec, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgNetworkBandwidthUsage { + const MESSAGE_TYPE: u16 = 189; + const MESSAGE_NAME: &'static str = "MSG_NETWORK_BANDWIDTH_USAGE"; } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} -impl TryFrom for MsgNetworkStateReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNetworkStateReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgNetworkBandwidthUsage { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgNetworkStateReq { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgNetworkBandwidthUsage { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNetworkBandwidthUsage(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgNetworkStateReq { sender_id: None } + + impl WireFormat for MsgNetworkBandwidthUsage { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.interfaces) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.interfaces, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgNetworkBandwidthUsage { + sender_id: None, + interfaces: WireFormat::parse_unchecked(buf), + } + } } } -/// State of network interface -/// -/// The state of a network interface on the Piksi. Data is made to reflect -/// output of ifaddrs struct returned by getifaddrs in c. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgNetworkStateResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// IPv4 address (all zero when unavailable) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv4_address")))] - pub ipv4_address: [u8; 4], - /// IPv4 netmask CIDR notation - #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv4_mask_size")))] - pub ipv4_mask_size: u8, - /// IPv6 address (all zero when unavailable) - #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv6_address")))] - pub ipv6_address: [u8; 16], - /// IPv6 netmask CIDR notation - #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv6_mask_size")))] - pub ipv6_mask_size: u8, - /// Number of Rx bytes - #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_bytes")))] - pub rx_bytes: u32, - /// Number of Tx bytes - #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_bytes")))] - pub tx_bytes: u32, - /// Interface Name - #[cfg_attr(feature = "serde", serde(rename(serialize = "interface_name")))] - pub interface_name: SbpString<[u8; 16], Unterminated>, - /// Interface flags from SIOCGIFFLAGS - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} +pub mod msg_network_state_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgNetworkStateResp { - const MESSAGE_TYPE: u16 = 187; - const MESSAGE_NAME: &'static str = "MSG_NETWORK_STATE_RESP"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgNetworkStateResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Request state of Piksi network interfaces + /// + /// Request state of Piksi network interfaces. Output will be sent in + /// MSG_NETWORK_STATE_RESP messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNetworkStateReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgNetworkStateReq { + const MESSAGE_TYPE: u16 = 186; + const MESSAGE_NAME: &'static str = "MSG_NETWORK_STATE_REQ"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgNetworkStateReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgNetworkStateResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgNetworkStateResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgNetworkStateReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNetworkStateReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgNetworkStateResp { - const MIN_LEN: usize = <[u8; 4] as WireFormat>::MIN_LEN - + ::MIN_LEN - + <[u8; 16] as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.ipv4_address) - + WireFormat::len(&self.ipv4_mask_size) - + WireFormat::len(&self.ipv6_address) - + WireFormat::len(&self.ipv6_mask_size) - + WireFormat::len(&self.rx_bytes) - + WireFormat::len(&self.tx_bytes) - + WireFormat::len(&self.interface_name) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.ipv4_address, buf); - WireFormat::write(&self.ipv4_mask_size, buf); - WireFormat::write(&self.ipv6_address, buf); - WireFormat::write(&self.ipv6_mask_size, buf); - WireFormat::write(&self.rx_bytes, buf); - WireFormat::write(&self.tx_bytes, buf); - WireFormat::write(&self.interface_name, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgNetworkStateResp { - sender_id: None, - ipv4_address: WireFormat::parse_unchecked(buf), - ipv4_mask_size: WireFormat::parse_unchecked(buf), - ipv6_address: WireFormat::parse_unchecked(buf), - ipv6_mask_size: WireFormat::parse_unchecked(buf), - rx_bytes: WireFormat::parse_unchecked(buf), - tx_bytes: WireFormat::parse_unchecked(buf), - interface_name: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgNetworkStateReq { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgNetworkStateReq { sender_id: None } } } } -/// Reset the device (host => Piksi) -/// -/// This message from the host resets the Piksi back into the bootloader. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgReset { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Reset flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} +pub mod msg_network_state_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// State of network interface + /// + /// The state of a network interface on the Piksi. Data is made to reflect + /// output of ifaddrs struct returned by getifaddrs in c. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgNetworkStateResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// IPv4 address (all zero when unavailable) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv4_address")))] + pub ipv4_address: [u8; 4], + /// IPv4 netmask CIDR notation + #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv4_mask_size")))] + pub ipv4_mask_size: u8, + /// IPv6 address (all zero when unavailable) + #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv6_address")))] + pub ipv6_address: [u8; 16], + /// IPv6 netmask CIDR notation + #[cfg_attr(feature = "serde", serde(rename(serialize = "ipv6_mask_size")))] + pub ipv6_mask_size: u8, + /// Number of Rx bytes + #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_bytes")))] + pub rx_bytes: u32, + /// Number of Tx bytes + #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_bytes")))] + pub tx_bytes: u32, + /// Interface Name + #[cfg_attr(feature = "serde", serde(rename(serialize = "interface_name")))] + pub interface_name: SbpString<[u8; 16], Unterminated>, + /// Interface flags from SIOCGIFFLAGS + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgNetworkStateResp { + /// Gets the `iff_multicast_supports_multicast` flag. + pub fn iff_multicast_supports_multicast(&self) -> bool { + ((self.flags >> 15) & 1) == 1 + } -impl ConcreteMessage for MsgReset { - const MESSAGE_TYPE: u16 = 182; - const MESSAGE_NAME: &'static str = "MSG_RESET"; -} + /// Sets the `iff_multicast_supports_multicast` flag. + pub fn set_iff_multicast_supports_multicast( + &mut self, + iff_multicast_supports_multicast: bool, + ) { + self.flags ^= (!(iff_multicast_supports_multicast as u32)) & (1 << 15) + } -impl SbpMessage for MsgReset { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the `iff_link2_per_link_layer_defined_bit` flag. + pub fn iff_link2_per_link_layer_defined_bit(&self) -> bool { + ((self.flags >> 14) & 1) == 1 + } -impl TryFrom for MsgReset { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgReset(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Sets the `iff_link2_per_link_layer_defined_bit` flag. + pub fn set_iff_link2_per_link_layer_defined_bit( + &mut self, + iff_link2_per_link_layer_defined_bit: bool, + ) { + self.flags ^= (!(iff_link2_per_link_layer_defined_bit as u32)) & (1 << 14) } - } -} -impl WireFormat for MsgReset { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgReset { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), + /// Gets the `iff_link1_per_link_layer_defined_bit` flag. + pub fn iff_link1_per_link_layer_defined_bit(&self) -> bool { + ((self.flags >> 13) & 1) == 1 } - } -} -/// Reset the device (host => Piksi) -/// -/// This message from the host resets the Piksi back into the bootloader. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgResetDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} + /// Sets the `iff_link1_per_link_layer_defined_bit` flag. + pub fn set_iff_link1_per_link_layer_defined_bit( + &mut self, + iff_link1_per_link_layer_defined_bit: bool, + ) { + self.flags ^= (!(iff_link1_per_link_layer_defined_bit as u32)) & (1 << 13) + } -impl ConcreteMessage for MsgResetDep { - const MESSAGE_TYPE: u16 = 178; - const MESSAGE_NAME: &'static str = "MSG_RESET_DEP"; -} + /// Gets the `iff_link0_per_link_layer_defined_bit` flag. + pub fn iff_link0_per_link_layer_defined_bit(&self) -> bool { + ((self.flags >> 12) & 1) == 1 + } -impl SbpMessage for MsgResetDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Sets the `iff_link0_per_link_layer_defined_bit` flag. + pub fn set_iff_link0_per_link_layer_defined_bit( + &mut self, + iff_link0_per_link_layer_defined_bit: bool, + ) { + self.flags ^= (!(iff_link0_per_link_layer_defined_bit as u32)) & (1 << 12) + } -impl TryFrom for MsgResetDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgResetDep(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Gets the `iff_simplex_cant_hear_own_transmissions` flag. + pub fn iff_simplex_cant_hear_own_transmissions(&self) -> bool { + ((self.flags >> 11) & 1) == 1 } - } -} -impl WireFormat for MsgResetDep { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 - } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgResetDep { sender_id: None } - } -} + /// Sets the `iff_simplex_cant_hear_own_transmissions` flag. + pub fn set_iff_simplex_cant_hear_own_transmissions( + &mut self, + iff_simplex_cant_hear_own_transmissions: bool, + ) { + self.flags ^= (!(iff_simplex_cant_hear_own_transmissions as u32)) & (1 << 11) + } -/// Reset IAR filters (host => Piksi) -/// -/// This message resets either the DGNSS Kalman filters or Integer Ambiguity -/// Resolution (IAR) process. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgResetFilters { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Filter flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "filter")))] - pub filter: u8, -} + /// Gets the `iff_oactive_transmission_in_progress` flag. + pub fn iff_oactive_transmission_in_progress(&self) -> bool { + ((self.flags >> 10) & 1) == 1 + } -impl ConcreteMessage for MsgResetFilters { - const MESSAGE_TYPE: u16 = 34; - const MESSAGE_NAME: &'static str = "MSG_RESET_FILTERS"; -} + /// Sets the `iff_oactive_transmission_in_progress` flag. + pub fn set_iff_oactive_transmission_in_progress( + &mut self, + iff_oactive_transmission_in_progress: bool, + ) { + self.flags ^= (!(iff_oactive_transmission_in_progress as u32)) & (1 << 10) + } -impl SbpMessage for MsgResetFilters { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Gets the `iff_allmulti_receive_all_multicast_packets` flag. + pub fn iff_allmulti_receive_all_multicast_packets(&self) -> bool { + ((self.flags >> 9) & 1) == 1 + } -impl TryFrom for MsgResetFilters { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgResetFilters(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Sets the `iff_allmulti_receive_all_multicast_packets` flag. + pub fn set_iff_allmulti_receive_all_multicast_packets( + &mut self, + iff_allmulti_receive_all_multicast_packets: bool, + ) { + self.flags ^= (!(iff_allmulti_receive_all_multicast_packets as u32)) & (1 << 9) } - } -} -impl WireFormat for MsgResetFilters { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.filter) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.filter, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgResetFilters { - sender_id: None, - filter: WireFormat::parse_unchecked(buf), + /// Gets the `iff_promisc_receive_all_packets` flag. + pub fn iff_promisc_receive_all_packets(&self) -> bool { + ((self.flags >> 8) & 1) == 1 } - } -} -/// Send GPS time from host (host => Piksi) -/// -/// This message sets up timing functionality using a coarse GPS time estimate -/// sent by the host. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSetTime { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} + /// Sets the `iff_promisc_receive_all_packets` flag. + pub fn set_iff_promisc_receive_all_packets( + &mut self, + iff_promisc_receive_all_packets: bool, + ) { + self.flags ^= (!(iff_promisc_receive_all_packets as u32)) & (1 << 8) + } -impl ConcreteMessage for MsgSetTime { - const MESSAGE_TYPE: u16 = 104; - const MESSAGE_NAME: &'static str = "MSG_SET_TIME"; -} + /// Gets the `iff_noarp_no_address_resolution_protocol` flag. + pub fn iff_noarp_no_address_resolution_protocol(&self) -> bool { + ((self.flags >> 7) & 1) == 1 + } -impl SbpMessage for MsgSetTime { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Sets the `iff_noarp_no_address_resolution_protocol` flag. + pub fn set_iff_noarp_no_address_resolution_protocol( + &mut self, + iff_noarp_no_address_resolution_protocol: bool, + ) { + self.flags ^= (!(iff_noarp_no_address_resolution_protocol as u32)) & (1 << 7) + } + + /// Gets the `iff_running_resources_allocated` flag. + pub fn iff_running_resources_allocated(&self) -> bool { + ((self.flags >> 6) & 1) == 1 + } + + /// Sets the `iff_running_resources_allocated` flag. + pub fn set_iff_running_resources_allocated( + &mut self, + iff_running_resources_allocated: bool, + ) { + self.flags ^= (!(iff_running_resources_allocated as u32)) & (1 << 6) + } + + /// Gets the `iff_notrailers_avoid_use_of_trailers` flag. + pub fn iff_notrailers_avoid_use_of_trailers(&self) -> bool { + ((self.flags >> 5) & 1) == 1 + } + + /// Sets the `iff_notrailers_avoid_use_of_trailers` flag. + pub fn set_iff_notrailers_avoid_use_of_trailers( + &mut self, + iff_notrailers_avoid_use_of_trailers: bool, + ) { + self.flags ^= (!(iff_notrailers_avoid_use_of_trailers as u32)) & (1 << 5) + } + + /// Gets the `iff_pointopoint_interface_is_pointtopoint_link` flag. + pub fn iff_pointopoint_interface_is_pointtopoint_link(&self) -> bool { + ((self.flags >> 4) & 1) == 1 + } + + /// Sets the `iff_pointopoint_interface_is_pointtopoint_link` flag. + pub fn set_iff_pointopoint_interface_is_pointtopoint_link( + &mut self, + iff_pointopoint_interface_is_pointtopoint_link: bool, + ) { + self.flags ^= (!(iff_pointopoint_interface_is_pointtopoint_link as u32)) & (1 << 4) + } + + /// Gets the `iff_loopback_is_a_loopback_net` flag. + pub fn iff_loopback_is_a_loopback_net(&self) -> bool { + ((self.flags >> 3) & 1) == 1 + } + + /// Sets the `iff_loopback_is_a_loopback_net` flag. + pub fn set_iff_loopback_is_a_loopback_net(&mut self, iff_loopback_is_a_loopback_net: bool) { + self.flags ^= (!(iff_loopback_is_a_loopback_net as u32)) & (1 << 3) + } + + /// Gets the `iff_debug_broadcast_address_valid` flag. + pub fn iff_debug_broadcast_address_valid(&self) -> bool { + ((self.flags >> 2) & 1) == 1 + } + + /// Sets the `iff_debug_broadcast_address_valid` flag. + pub fn set_iff_debug_broadcast_address_valid( + &mut self, + iff_debug_broadcast_address_valid: bool, + ) { + self.flags ^= (!(iff_debug_broadcast_address_valid as u32)) & (1 << 2) + } + + /// Gets the `iff_broadcast_broadcast_address_valid` flag. + pub fn iff_broadcast_broadcast_address_valid(&self) -> bool { + ((self.flags >> 1) & 1) == 1 + } + + /// Sets the `iff_broadcast_broadcast_address_valid` flag. + pub fn set_iff_broadcast_broadcast_address_valid( + &mut self, + iff_broadcast_broadcast_address_valid: bool, + ) { + self.flags ^= (!(iff_broadcast_broadcast_address_valid as u32)) & (1 << 1) + } + + /// Gets the `iff_up_interface_is_up` flag. + pub fn iff_up_interface_is_up(&self) -> bool { + ((self.flags >> 0) & 1) == 1 + } + + /// Sets the `iff_up_interface_is_up` flag. + pub fn set_iff_up_interface_is_up(&mut self, iff_up_interface_is_up: bool) { + self.flags ^= (!(iff_up_interface_is_up as u32)) & (1 << 0) + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgNetworkStateResp { + const MESSAGE_TYPE: u16 = 187; + const MESSAGE_NAME: &'static str = "MSG_NETWORK_STATE_RESP"; } -} -impl TryFrom for MsgSetTime { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSetTime(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgNetworkStateResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSetTime { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgNetworkStateResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgNetworkStateResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgSetTime { sender_id: None } + + impl WireFormat for MsgNetworkStateResp { + const MIN_LEN: usize = <[u8; 4] as WireFormat>::MIN_LEN + + ::MIN_LEN + + <[u8; 16] as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.ipv4_address) + + WireFormat::len(&self.ipv4_mask_size) + + WireFormat::len(&self.ipv6_address) + + WireFormat::len(&self.ipv6_mask_size) + + WireFormat::len(&self.rx_bytes) + + WireFormat::len(&self.tx_bytes) + + WireFormat::len(&self.interface_name) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.ipv4_address, buf); + WireFormat::write(&self.ipv4_mask_size, buf); + WireFormat::write(&self.ipv6_address, buf); + WireFormat::write(&self.ipv6_mask_size, buf); + WireFormat::write(&self.rx_bytes, buf); + WireFormat::write(&self.tx_bytes, buf); + WireFormat::write(&self.interface_name, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgNetworkStateResp { + sender_id: None, + ipv4_address: WireFormat::parse_unchecked(buf), + ipv4_mask_size: WireFormat::parse_unchecked(buf), + ipv6_address: WireFormat::parse_unchecked(buf), + ipv6_mask_size: WireFormat::parse_unchecked(buf), + rx_bytes: WireFormat::parse_unchecked(buf), + tx_bytes: WireFormat::parse_unchecked(buf), + interface_name: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } } -/// Spectrum analyzer -/// -/// Spectrum analyzer packet. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSpecan { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Channel ID - #[cfg_attr(feature = "serde", serde(rename(serialize = "channel_tag")))] - pub channel_tag: u16, - /// Receiver time of this observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: GpsTime, - /// Reference frequency of this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_ref")))] - pub freq_ref: f32, - /// Frequency step of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_step")))] - pub freq_step: f32, - /// Reference amplitude of this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_ref")))] - pub amplitude_ref: f32, - /// Amplitude unit value of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_unit")))] - pub amplitude_unit: f32, - /// Amplitude values (in the above units) of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_value")))] - pub amplitude_value: Vec, -} +pub mod msg_reset { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Reset the device (host => Piksi) + /// + /// This message from the host resets the Piksi back into the bootloader. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgReset { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Reset flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgReset { + /// Gets the [DefaultSettings][self::DefaultSettings] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `DefaultSettings` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `DefaultSettings` were added. + pub fn default_settings(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 0, 0).try_into() + } -impl ConcreteMessage for MsgSpecan { - const MESSAGE_TYPE: u16 = 81; - const MESSAGE_NAME: &'static str = "MSG_SPECAN"; -} + /// Set the bitrange corresponding to the [DefaultSettings][DefaultSettings] of the `flags` bitfield. + pub fn set_default_settings(&mut self, default_settings: DefaultSettings) { + set_bit_range!(&mut self.flags, default_settings, u32, u8, 0, 0); + } + } -impl SbpMessage for MsgSpecan { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl ConcreteMessage for MsgReset { + const MESSAGE_TYPE: u16 = 182; + const MESSAGE_NAME: &'static str = "MSG_RESET"; } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl SbpMessage for MsgReset { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MsgReset { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgReset(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl WireFormat for MsgReset { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgReset { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Default settings. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum DefaultSettings { + /// Preserve existing settings. + PreserveExistingSettings = 0, + + /// Resore default settings. + ResoreDefaultSettings = 1, } -} -impl TryFrom for MsgSpecan { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSpecan(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for DefaultSettings { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DefaultSettings::PreserveExistingSettings => { + f.write_str("Preserve existing settings.") + } + DefaultSettings::ResoreDefaultSettings => f.write_str("Resore default settings."), + } } } -} -impl WireFormat for MsgSpecan { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.channel_tag) - + WireFormat::len(&self.t) - + WireFormat::len(&self.freq_ref) - + WireFormat::len(&self.freq_step) - + WireFormat::len(&self.amplitude_ref) - + WireFormat::len(&self.amplitude_unit) - + WireFormat::len(&self.amplitude_value) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.channel_tag, buf); - WireFormat::write(&self.t, buf); - WireFormat::write(&self.freq_ref, buf); - WireFormat::write(&self.freq_step, buf); - WireFormat::write(&self.amplitude_ref, buf); - WireFormat::write(&self.amplitude_unit, buf); - WireFormat::write(&self.amplitude_value, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSpecan { - sender_id: None, - channel_tag: WireFormat::parse_unchecked(buf), - t: WireFormat::parse_unchecked(buf), - freq_ref: WireFormat::parse_unchecked(buf), - freq_step: WireFormat::parse_unchecked(buf), - amplitude_ref: WireFormat::parse_unchecked(buf), - amplitude_unit: WireFormat::parse_unchecked(buf), - amplitude_value: WireFormat::parse_unchecked(buf), + impl TryFrom for DefaultSettings { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(DefaultSettings::PreserveExistingSettings), + 1 => Ok(DefaultSettings::ResoreDefaultSettings), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSpecanDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Channel ID - #[cfg_attr(feature = "serde", serde(rename(serialize = "channel_tag")))] - pub channel_tag: u16, - /// Receiver time of this observation - #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] - pub t: GpsTimeDep, - /// Reference frequency of this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_ref")))] - pub freq_ref: f32, - /// Frequency step of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_step")))] - pub freq_step: f32, - /// Reference amplitude of this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_ref")))] - pub amplitude_ref: f32, - /// Amplitude unit value of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_unit")))] - pub amplitude_unit: f32, - /// Amplitude values (in the above units) of points in this packet - #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_value")))] - pub amplitude_value: Vec, -} +pub mod msg_reset_dep { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSpecanDep { - const MESSAGE_TYPE: u16 = 80; - const MESSAGE_NAME: &'static str = "MSG_SPECAN_DEP"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSpecanDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Reset the device (host => Piksi) + /// + /// This message from the host resets the Piksi back into the bootloader. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgResetDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgResetDep { + const MESSAGE_TYPE: u16 = 178; + const MESSAGE_NAME: &'static str = "MSG_RESET_DEP"; } -} -impl TryFrom for MsgSpecanDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSpecanDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgResetDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSpecanDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.channel_tag) - + WireFormat::len(&self.t) - + WireFormat::len(&self.freq_ref) - + WireFormat::len(&self.freq_step) - + WireFormat::len(&self.amplitude_ref) - + WireFormat::len(&self.amplitude_unit) - + WireFormat::len(&self.amplitude_value) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.channel_tag, buf); - WireFormat::write(&self.t, buf); - WireFormat::write(&self.freq_ref, buf); - WireFormat::write(&self.freq_step, buf); - WireFormat::write(&self.amplitude_ref, buf); - WireFormat::write(&self.amplitude_unit, buf); - WireFormat::write(&self.amplitude_value, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSpecanDep { - sender_id: None, - channel_tag: WireFormat::parse_unchecked(buf), - t: WireFormat::parse_unchecked(buf), - freq_ref: WireFormat::parse_unchecked(buf), - freq_step: WireFormat::parse_unchecked(buf), - amplitude_ref: WireFormat::parse_unchecked(buf), - amplitude_unit: WireFormat::parse_unchecked(buf), - amplitude_value: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgResetDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgResetDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// State of an RTOS thread -/// -/// The thread usage message from the device reports real-time operating -/// system (RTOS) thread usage statistics for the named thread. The reported -/// percentage values must be normalized. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgThreadState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Thread name (NULL terminated) - #[cfg_attr(feature = "serde", serde(rename(serialize = "name")))] - pub name: SbpString<[u8; 20], NullTerminated>, - /// Percentage cpu use for this thread. Values range from 0 - 1000 and needs - /// to be renormalized to 100 - #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu")))] - pub cpu: u16, - /// Free stack space for this thread - #[cfg_attr(feature = "serde", serde(rename(serialize = "stack_free")))] - pub stack_free: u32, + impl WireFormat for MsgResetDep { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgResetDep { sender_id: None } + } + } } -impl ConcreteMessage for MsgThreadState { - const MESSAGE_TYPE: u16 = 23; - const MESSAGE_NAME: &'static str = "MSG_THREAD_STATE"; -} +pub mod msg_reset_filters { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Reset IAR filters (host => Piksi) + /// + /// This message resets either the DGNSS Kalman filters or Integer Ambiguity + /// Resolution (IAR) process. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgResetFilters { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Filter flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "filter")))] + pub filter: u8, + } + + impl MsgResetFilters { + /// Gets the [FilterOrProcessToReset][self::FilterOrProcessToReset] stored in the `filter` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FilterOrProcessToReset` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FilterOrProcessToReset` were added. + pub fn filter_or_process_to_reset(&self) -> Result { + get_bit_range!(self.filter, u8, u8, 1, 0).try_into() + } -impl SbpMessage for MsgThreadState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Set the bitrange corresponding to the [FilterOrProcessToReset][FilterOrProcessToReset] of the `filter` bitfield. + pub fn set_filter_or_process_to_reset( + &mut self, + filter_or_process_to_reset: FilterOrProcessToReset, + ) { + set_bit_range!(&mut self.filter, filter_or_process_to_reset, u8, u8, 1, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgResetFilters { + const MESSAGE_TYPE: u16 = 34; + const MESSAGE_NAME: &'static str = "MSG_RESET_FILTERS"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgResetFilters { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgResetFilters { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgResetFilters(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgThreadState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgThreadState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgResetFilters { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.filter) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.filter, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgResetFilters { + sender_id: None, + filter: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgThreadState { - const MIN_LEN: usize = as WireFormat>::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.name) + WireFormat::len(&self.cpu) + WireFormat::len(&self.stack_free) + /// Filter or process to reset + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FilterOrProcessToReset { + /// DGNSS filter + DgnssFilter = 0, + + /// IAR process + IarProcess = 1, + + /// Inertial filter + InertialFilter = 2, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.name, buf); - WireFormat::write(&self.cpu, buf); - WireFormat::write(&self.stack_free, buf); + + impl std::fmt::Display for FilterOrProcessToReset { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FilterOrProcessToReset::DgnssFilter => f.write_str("DGNSS filter"), + FilterOrProcessToReset::IarProcess => f.write_str("IAR process"), + FilterOrProcessToReset::InertialFilter => f.write_str("Inertial filter"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgThreadState { - sender_id: None, - name: WireFormat::parse_unchecked(buf), - cpu: WireFormat::parse_unchecked(buf), - stack_free: WireFormat::parse_unchecked(buf), + + impl TryFrom for FilterOrProcessToReset { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FilterOrProcessToReset::DgnssFilter), + 1 => Ok(FilterOrProcessToReset::IarProcess), + 2 => Ok(FilterOrProcessToReset::InertialFilter), + i => Err(i), + } } } } -/// State of the UART channels -/// -/// The UART message reports data latency and throughput of the UART channels -/// providing SBP I/O. On the default Piksi configuration, UARTs A and B are -/// used for telemetry radios, but can also be host access ports for embedded -/// hosts, or other interfaces in future. The reported percentage values must -/// be normalized. Observations latency and period can be used to assess the -/// health of the differential corrections link. Latency provides the -/// timeliness of received base observations while the period indicates their -/// likelihood of transmission. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgUartState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// State of UART A - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_a")))] - pub uart_a: UARTChannel, - /// State of UART B - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_b")))] - pub uart_b: UARTChannel, - /// State of UART FTDI (USB logger) - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_ftdi")))] - pub uart_ftdi: UARTChannel, - /// UART communication latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] - pub latency: Latency, - /// Observation receipt period - #[cfg_attr(feature = "serde", serde(rename(serialize = "obs_period")))] - pub obs_period: Period, -} +pub mod msg_set_time { + #![allow(unused_imports)] -impl ConcreteMessage for MsgUartState { - const MESSAGE_TYPE: u16 = 29; - const MESSAGE_NAME: &'static str = "MSG_UART_STATE"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgUartState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Send GPS time from host (host => Piksi) + /// + /// This message sets up timing functionality using a coarse GPS time estimate + /// sent by the host. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSetTime { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgSetTime { + const MESSAGE_TYPE: u16 = 104; + const MESSAGE_NAME: &'static str = "MSG_SET_TIME"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgSetTime { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgSetTime { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSetTime(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgSetTime { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgSetTime { sender_id: None } + } } } -impl TryFrom for MsgUartState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgUartState(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_specan { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Spectrum analyzer + /// + /// Spectrum analyzer packet. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSpecan { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Channel ID + #[cfg_attr(feature = "serde", serde(rename(serialize = "channel_tag")))] + pub channel_tag: u16, + /// Receiver time of this observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: GpsTime, + /// Reference frequency of this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_ref")))] + pub freq_ref: f32, + /// Frequency step of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_step")))] + pub freq_step: f32, + /// Reference amplitude of this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_ref")))] + pub amplitude_ref: f32, + /// Amplitude unit value of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_unit")))] + pub amplitude_unit: f32, + /// Amplitude values (in the above units) of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_value")))] + pub amplitude_value: Vec, + } + + impl ConcreteMessage for MsgSpecan { + const MESSAGE_TYPE: u16 = 81; + const MESSAGE_NAME: &'static str = "MSG_SPECAN"; + } + + impl SbpMessage for MsgSpecan { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgUartState { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.uart_a) - + WireFormat::len(&self.uart_b) - + WireFormat::len(&self.uart_ftdi) - + WireFormat::len(&self.latency) - + WireFormat::len(&self.obs_period) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.uart_a, buf); - WireFormat::write(&self.uart_b, buf); - WireFormat::write(&self.uart_ftdi, buf); - WireFormat::write(&self.latency, buf); - WireFormat::write(&self.obs_period, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgUartState { - sender_id: None, - uart_a: WireFormat::parse_unchecked(buf), - uart_b: WireFormat::parse_unchecked(buf), - uart_ftdi: WireFormat::parse_unchecked(buf), - latency: WireFormat::parse_unchecked(buf), - obs_period: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSpecan { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSpecan(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Deprecated -/// -/// Deprecated -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgUartStateDepa { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// State of UART A - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_a")))] - pub uart_a: UARTChannel, - /// State of UART B - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_b")))] - pub uart_b: UARTChannel, - /// State of UART FTDI (USB logger) - #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_ftdi")))] - pub uart_ftdi: UARTChannel, - /// UART communication latency - #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] - pub latency: Latency, + impl WireFormat for MsgSpecan { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.channel_tag) + + WireFormat::len(&self.t) + + WireFormat::len(&self.freq_ref) + + WireFormat::len(&self.freq_step) + + WireFormat::len(&self.amplitude_ref) + + WireFormat::len(&self.amplitude_unit) + + WireFormat::len(&self.amplitude_value) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.channel_tag, buf); + WireFormat::write(&self.t, buf); + WireFormat::write(&self.freq_ref, buf); + WireFormat::write(&self.freq_step, buf); + WireFormat::write(&self.amplitude_ref, buf); + WireFormat::write(&self.amplitude_unit, buf); + WireFormat::write(&self.amplitude_value, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSpecan { + sender_id: None, + channel_tag: WireFormat::parse_unchecked(buf), + t: WireFormat::parse_unchecked(buf), + freq_ref: WireFormat::parse_unchecked(buf), + freq_step: WireFormat::parse_unchecked(buf), + amplitude_ref: WireFormat::parse_unchecked(buf), + amplitude_unit: WireFormat::parse_unchecked(buf), + amplitude_value: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgUartStateDepa { - const MESSAGE_TYPE: u16 = 24; - const MESSAGE_NAME: &'static str = "MSG_UART_STATE_DEPA"; -} +pub mod msg_specan_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSpecanDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Channel ID + #[cfg_attr(feature = "serde", serde(rename(serialize = "channel_tag")))] + pub channel_tag: u16, + /// Receiver time of this observation + #[cfg_attr(feature = "serde", serde(rename(serialize = "t")))] + pub t: GpsTimeDep, + /// Reference frequency of this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_ref")))] + pub freq_ref: f32, + /// Frequency step of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "freq_step")))] + pub freq_step: f32, + /// Reference amplitude of this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_ref")))] + pub amplitude_ref: f32, + /// Amplitude unit value of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_unit")))] + pub amplitude_unit: f32, + /// Amplitude values (in the above units) of points in this packet + #[cfg_attr(feature = "serde", serde(rename(serialize = "amplitude_value")))] + pub amplitude_value: Vec, + } + + impl ConcreteMessage for MsgSpecanDep { + const MESSAGE_TYPE: u16 = 80; + const MESSAGE_NAME: &'static str = "MSG_SPECAN_DEP"; + } + + impl SbpMessage for MsgSpecanDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } -impl SbpMessage for MsgUartStateDepa { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl TryFrom for MsgSpecanDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSpecanDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl WireFormat for MsgSpecanDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.channel_tag) + + WireFormat::len(&self.t) + + WireFormat::len(&self.freq_ref) + + WireFormat::len(&self.freq_step) + + WireFormat::len(&self.amplitude_ref) + + WireFormat::len(&self.amplitude_unit) + + WireFormat::len(&self.amplitude_value) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.channel_tag, buf); + WireFormat::write(&self.t, buf); + WireFormat::write(&self.freq_ref, buf); + WireFormat::write(&self.freq_step, buf); + WireFormat::write(&self.amplitude_ref, buf); + WireFormat::write(&self.amplitude_unit, buf); + WireFormat::write(&self.amplitude_value, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSpecanDep { + sender_id: None, + channel_tag: WireFormat::parse_unchecked(buf), + t: WireFormat::parse_unchecked(buf), + freq_ref: WireFormat::parse_unchecked(buf), + freq_step: WireFormat::parse_unchecked(buf), + amplitude_ref: WireFormat::parse_unchecked(buf), + amplitude_unit: WireFormat::parse_unchecked(buf), + amplitude_value: WireFormat::parse_unchecked(buf), + } + } } - fn sender_id(&self) -> Option { - self.sender_id +} + +pub mod msg_thread_state { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// State of an RTOS thread + /// + /// The thread usage message from the device reports real-time operating + /// system (RTOS) thread usage statistics for the named thread. The reported + /// percentage values must be normalized. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgThreadState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Thread name (NULL terminated) + #[cfg_attr(feature = "serde", serde(rename(serialize = "name")))] + pub name: SbpString<[u8; 20], NullTerminated>, + /// Percentage cpu use for this thread. Values range from 0 - 1000 and needs + /// to be renormalized to 100 + #[cfg_attr(feature = "serde", serde(rename(serialize = "cpu")))] + pub cpu: u16, + /// Free stack space for this thread + #[cfg_attr(feature = "serde", serde(rename(serialize = "stack_free")))] + pub stack_free: u32, + } + + impl ConcreteMessage for MsgThreadState { + const MESSAGE_TYPE: u16 = 23; + const MESSAGE_NAME: &'static str = "MSG_THREAD_STATE"; + } + + impl SbpMessage for MsgThreadState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgThreadState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgThreadState(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgThreadState { + const MIN_LEN: usize = as WireFormat>::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.name) + + WireFormat::len(&self.cpu) + + WireFormat::len(&self.stack_free) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.name, buf); + WireFormat::write(&self.cpu, buf); + WireFormat::write(&self.stack_free, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgThreadState { + sender_id: None, + name: WireFormat::parse_unchecked(buf), + cpu: WireFormat::parse_unchecked(buf), + stack_free: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgUartStateDepa { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgUartStateDepa(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_uart_state { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// State of the UART channels + /// + /// The UART message reports data latency and throughput of the UART channels + /// providing SBP I/O. On the default Piksi configuration, UARTs A and B are + /// used for telemetry radios, but can also be host access ports for embedded + /// hosts, or other interfaces in future. The reported percentage values must + /// be normalized. Observations latency and period can be used to assess the + /// health of the differential corrections link. Latency provides the + /// timeliness of received base observations while the period indicates their + /// likelihood of transmission. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgUartState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// State of UART A + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_a")))] + pub uart_a: UARTChannel, + /// State of UART B + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_b")))] + pub uart_b: UARTChannel, + /// State of UART FTDI (USB logger) + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_ftdi")))] + pub uart_ftdi: UARTChannel, + /// UART communication latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] + pub latency: Latency, + /// Observation receipt period + #[cfg_attr(feature = "serde", serde(rename(serialize = "obs_period")))] + pub obs_period: Period, + } + + impl ConcreteMessage for MsgUartState { + const MESSAGE_TYPE: u16 = 29; + const MESSAGE_NAME: &'static str = "MSG_UART_STATE"; + } + + impl SbpMessage for MsgUartState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgUartStateDepa { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.uart_a) - + WireFormat::len(&self.uart_b) - + WireFormat::len(&self.uart_ftdi) - + WireFormat::len(&self.latency) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.uart_a, buf); - WireFormat::write(&self.uart_b, buf); - WireFormat::write(&self.uart_ftdi, buf); - WireFormat::write(&self.latency, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgUartStateDepa { - sender_id: None, - uart_a: WireFormat::parse_unchecked(buf), - uart_b: WireFormat::parse_unchecked(buf), - uart_ftdi: WireFormat::parse_unchecked(buf), - latency: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgUartState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgUartState(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Bandwidth usage measurement for a single interface -/// -/// The bandwidth usage for each interface can be reported within this struct -/// and utilize multiple fields to fully specify the type of traffic that is -/// being tracked. As either the interval of collection or the collection time -/// may vary, both a timestamp and period field is provided, though may not -/// necessarily be populated with a value. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct NetworkUsage { - /// Duration over which the measurement was collected - #[cfg_attr(feature = "serde", serde(rename(serialize = "duration")))] - pub duration: u64, - /// Number of bytes handled in total within period - #[cfg_attr(feature = "serde", serde(rename(serialize = "total_bytes")))] - pub total_bytes: u64, - /// Number of bytes transmitted within period - #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_bytes")))] - pub rx_bytes: u32, - /// Number of bytes received within period - #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_bytes")))] - pub tx_bytes: u32, - /// Interface Name - #[cfg_attr(feature = "serde", serde(rename(serialize = "interface_name")))] - pub interface_name: SbpString<[u8; 16], Unterminated>, + impl WireFormat for MsgUartState { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.uart_a) + + WireFormat::len(&self.uart_b) + + WireFormat::len(&self.uart_ftdi) + + WireFormat::len(&self.latency) + + WireFormat::len(&self.obs_period) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.uart_a, buf); + WireFormat::write(&self.uart_b, buf); + WireFormat::write(&self.uart_ftdi, buf); + WireFormat::write(&self.latency, buf); + WireFormat::write(&self.obs_period, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgUartState { + sender_id: None, + uart_a: WireFormat::parse_unchecked(buf), + uart_b: WireFormat::parse_unchecked(buf), + uart_ftdi: WireFormat::parse_unchecked(buf), + latency: WireFormat::parse_unchecked(buf), + obs_period: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for NetworkUsage { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.duration) - + WireFormat::len(&self.total_bytes) - + WireFormat::len(&self.rx_bytes) - + WireFormat::len(&self.tx_bytes) - + WireFormat::len(&self.interface_name) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.duration, buf); - WireFormat::write(&self.total_bytes, buf); - WireFormat::write(&self.rx_bytes, buf); - WireFormat::write(&self.tx_bytes, buf); - WireFormat::write(&self.interface_name, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - NetworkUsage { - duration: WireFormat::parse_unchecked(buf), - total_bytes: WireFormat::parse_unchecked(buf), - rx_bytes: WireFormat::parse_unchecked(buf), - tx_bytes: WireFormat::parse_unchecked(buf), - interface_name: WireFormat::parse_unchecked(buf), +pub mod msg_uart_state_depa { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgUartStateDepa { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// State of UART A + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_a")))] + pub uart_a: UARTChannel, + /// State of UART B + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_b")))] + pub uart_b: UARTChannel, + /// State of UART FTDI (USB logger) + #[cfg_attr(feature = "serde", serde(rename(serialize = "uart_ftdi")))] + pub uart_ftdi: UARTChannel, + /// UART communication latency + #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] + pub latency: Latency, + } + + impl ConcreteMessage for MsgUartStateDepa { + const MESSAGE_TYPE: u16 = 24; + const MESSAGE_NAME: &'static str = "MSG_UART_STATE_DEPA"; + } + + impl SbpMessage for MsgUartStateDepa { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgUartStateDepa { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgUartStateDepa(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// base station observation message receipt period -/// -/// Statistics on the period of observations received from the base station. -/// As complete observation sets are received, their time of reception is -/// compared with the prior set''s time of reception. This measurement -/// provides a proxy for link quality as incomplete or missing sets will -/// increase the period. Long periods can cause momentary RTK solution -/// outages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct Period { - /// Average period - #[cfg_attr(feature = "serde", serde(rename(serialize = "avg")))] - pub avg: i32, - /// Minimum period - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmin")))] - pub pmin: i32, - /// Maximum period - #[cfg_attr(feature = "serde", serde(rename(serialize = "pmax")))] - pub pmax: i32, - /// Smoothed estimate of the current period - #[cfg_attr(feature = "serde", serde(rename(serialize = "current")))] - pub current: i32, + impl WireFormat for MsgUartStateDepa { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.uart_a) + + WireFormat::len(&self.uart_b) + + WireFormat::len(&self.uart_ftdi) + + WireFormat::len(&self.latency) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.uart_a, buf); + WireFormat::write(&self.uart_b, buf); + WireFormat::write(&self.uart_ftdi, buf); + WireFormat::write(&self.latency, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgUartStateDepa { + sender_id: None, + uart_a: WireFormat::parse_unchecked(buf), + uart_b: WireFormat::parse_unchecked(buf), + uart_ftdi: WireFormat::parse_unchecked(buf), + latency: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for Period { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.avg) - + WireFormat::len(&self.pmin) - + WireFormat::len(&self.pmax) - + WireFormat::len(&self.current) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.avg, buf); - WireFormat::write(&self.pmin, buf); - WireFormat::write(&self.pmax, buf); - WireFormat::write(&self.current, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - Period { - avg: WireFormat::parse_unchecked(buf), - pmin: WireFormat::parse_unchecked(buf), - pmax: WireFormat::parse_unchecked(buf), - current: WireFormat::parse_unchecked(buf), +pub mod network_usage { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Bandwidth usage measurement for a single interface + /// + /// The bandwidth usage for each interface can be reported within this struct + /// and utilize multiple fields to fully specify the type of traffic that is + /// being tracked. As either the interval of collection or the collection time + /// may vary, both a timestamp and period field is provided, though may not + /// necessarily be populated with a value. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct NetworkUsage { + /// Duration over which the measurement was collected + #[cfg_attr(feature = "serde", serde(rename(serialize = "duration")))] + pub duration: u64, + /// Number of bytes handled in total within period + #[cfg_attr(feature = "serde", serde(rename(serialize = "total_bytes")))] + pub total_bytes: u64, + /// Number of bytes transmitted within period + #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_bytes")))] + pub rx_bytes: u32, + /// Number of bytes received within period + #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_bytes")))] + pub tx_bytes: u32, + /// Interface Name + #[cfg_attr(feature = "serde", serde(rename(serialize = "interface_name")))] + pub interface_name: SbpString<[u8; 16], Unterminated>, + } + + impl WireFormat for NetworkUsage { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.duration) + + WireFormat::len(&self.total_bytes) + + WireFormat::len(&self.rx_bytes) + + WireFormat::len(&self.tx_bytes) + + WireFormat::len(&self.interface_name) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.duration, buf); + WireFormat::write(&self.total_bytes, buf); + WireFormat::write(&self.rx_bytes, buf); + WireFormat::write(&self.tx_bytes, buf); + WireFormat::write(&self.interface_name, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + NetworkUsage { + duration: WireFormat::parse_unchecked(buf), + total_bytes: WireFormat::parse_unchecked(buf), + rx_bytes: WireFormat::parse_unchecked(buf), + tx_bytes: WireFormat::parse_unchecked(buf), + interface_name: WireFormat::parse_unchecked(buf), + } } } } -/// State of the UART channel -/// -/// Throughput, utilization, and error counts on the RX/TX buffers of this -/// UART channel. The reported percentage values must be normalized. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct UARTChannel { - /// UART transmit throughput - #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_throughput")))] - pub tx_throughput: f32, - /// UART receive throughput - #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_throughput")))] - pub rx_throughput: f32, - /// UART CRC error count - #[cfg_attr(feature = "serde", serde(rename(serialize = "crc_error_count")))] - pub crc_error_count: u16, - /// UART IO error count - #[cfg_attr(feature = "serde", serde(rename(serialize = "io_error_count")))] - pub io_error_count: u16, - /// UART transmit buffer percentage utilization (ranges from 0 to 255) - #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_buffer_level")))] - pub tx_buffer_level: u8, - /// UART receive buffer percentage utilization (ranges from 0 to 255) - #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_buffer_level")))] - pub rx_buffer_level: u8, +pub mod period { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// base station observation message receipt period + /// + /// Statistics on the period of observations received from the base station. + /// As complete observation sets are received, their time of reception is + /// compared with the prior set''s time of reception. This measurement + /// provides a proxy for link quality as incomplete or missing sets will + /// increase the period. Long periods can cause momentary RTK solution + /// outages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct Period { + /// Average period + #[cfg_attr(feature = "serde", serde(rename(serialize = "avg")))] + pub avg: i32, + /// Minimum period + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmin")))] + pub pmin: i32, + /// Maximum period + #[cfg_attr(feature = "serde", serde(rename(serialize = "pmax")))] + pub pmax: i32, + /// Smoothed estimate of the current period + #[cfg_attr(feature = "serde", serde(rename(serialize = "current")))] + pub current: i32, + } + + impl WireFormat for Period { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.avg) + + WireFormat::len(&self.pmin) + + WireFormat::len(&self.pmax) + + WireFormat::len(&self.current) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.avg, buf); + WireFormat::write(&self.pmin, buf); + WireFormat::write(&self.pmax, buf); + WireFormat::write(&self.current, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + Period { + avg: WireFormat::parse_unchecked(buf), + pmin: WireFormat::parse_unchecked(buf), + pmax: WireFormat::parse_unchecked(buf), + current: WireFormat::parse_unchecked(buf), + } + } + } } -impl WireFormat for UARTChannel { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tx_throughput) - + WireFormat::len(&self.rx_throughput) - + WireFormat::len(&self.crc_error_count) - + WireFormat::len(&self.io_error_count) - + WireFormat::len(&self.tx_buffer_level) - + WireFormat::len(&self.rx_buffer_level) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tx_throughput, buf); - WireFormat::write(&self.rx_throughput, buf); - WireFormat::write(&self.crc_error_count, buf); - WireFormat::write(&self.io_error_count, buf); - WireFormat::write(&self.tx_buffer_level, buf); - WireFormat::write(&self.rx_buffer_level, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - UARTChannel { - tx_throughput: WireFormat::parse_unchecked(buf), - rx_throughput: WireFormat::parse_unchecked(buf), - crc_error_count: WireFormat::parse_unchecked(buf), - io_error_count: WireFormat::parse_unchecked(buf), - tx_buffer_level: WireFormat::parse_unchecked(buf), - rx_buffer_level: WireFormat::parse_unchecked(buf), +pub mod uart_channel { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// State of the UART channel + /// + /// Throughput, utilization, and error counts on the RX/TX buffers of this + /// UART channel. The reported percentage values must be normalized. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct UARTChannel { + /// UART transmit throughput + #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_throughput")))] + pub tx_throughput: f32, + /// UART receive throughput + #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_throughput")))] + pub rx_throughput: f32, + /// UART CRC error count + #[cfg_attr(feature = "serde", serde(rename(serialize = "crc_error_count")))] + pub crc_error_count: u16, + /// UART IO error count + #[cfg_attr(feature = "serde", serde(rename(serialize = "io_error_count")))] + pub io_error_count: u16, + /// UART transmit buffer percentage utilization (ranges from 0 to 255) + #[cfg_attr(feature = "serde", serde(rename(serialize = "tx_buffer_level")))] + pub tx_buffer_level: u8, + /// UART receive buffer percentage utilization (ranges from 0 to 255) + #[cfg_attr(feature = "serde", serde(rename(serialize = "rx_buffer_level")))] + pub rx_buffer_level: u8, + } + + impl WireFormat for UARTChannel { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tx_throughput) + + WireFormat::len(&self.rx_throughput) + + WireFormat::len(&self.crc_error_count) + + WireFormat::len(&self.io_error_count) + + WireFormat::len(&self.tx_buffer_level) + + WireFormat::len(&self.rx_buffer_level) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tx_throughput, buf); + WireFormat::write(&self.rx_throughput, buf); + WireFormat::write(&self.crc_error_count, buf); + WireFormat::write(&self.io_error_count, buf); + WireFormat::write(&self.tx_buffer_level, buf); + WireFormat::write(&self.rx_buffer_level, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + UARTChannel { + tx_throughput: WireFormat::parse_unchecked(buf), + rx_throughput: WireFormat::parse_unchecked(buf), + crc_error_count: WireFormat::parse_unchecked(buf), + io_error_count: WireFormat::parse_unchecked(buf), + tx_buffer_level: WireFormat::parse_unchecked(buf), + rx_buffer_level: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/sbas.rs b/rust/sbp/src/messages/sbas.rs index 43357da973..7d40e0d49e 100644 --- a/rust/sbp/src/messages/sbas.rs +++ b/rust/sbp/src/messages/sbas.rs @@ -13,102 +13,107 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! SBAS data +pub use msg_sbas_raw::MsgSbasRaw; -use super::gnss::*; +pub mod msg_sbas_raw { + #![allow(unused_imports)] -use super::lib::*; + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -/// Raw SBAS data -/// -/// This message is sent once per second per SBAS satellite. ME checks the -/// parity of the data block and sends only blocks that pass the check. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSbasRaw { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GNSS signal identifier. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// GPS time-of-week at the start of the data block. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// SBAS message type (0-63) - #[cfg_attr(feature = "serde", serde(rename(serialize = "message_type")))] - pub message_type: u8, - /// Raw SBAS data field of 212 bits (last byte padded with zeros). - #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] - pub data: [u8; 27], -} - -impl ConcreteMessage for MsgSbasRaw { - const MESSAGE_TYPE: u16 = 30583; - const MESSAGE_NAME: &'static str = "MSG_SBAS_RAW"; -} - -impl SbpMessage for MsgSbasRaw { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Raw SBAS data + /// + /// This message is sent once per second per SBAS satellite. ME checks the + /// parity of the data block and sends only blocks that pass the check. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSbasRaw { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GNSS signal identifier. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// GPS time-of-week at the start of the data block. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// SBAS message type (0-63) + #[cfg_attr(feature = "serde", serde(rename(serialize = "message_type")))] + pub message_type: u8, + /// Raw SBAS data field of 212 bits (last byte padded with zeros). + #[cfg_attr(feature = "serde", serde(rename(serialize = "data")))] + pub data: [u8; 27], } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl ConcreteMessage for MsgSbasRaw { + const MESSAGE_TYPE: u16 = 30583; + const MESSAGE_NAME: &'static str = "MSG_SBAS_RAW"; } -} -impl TryFrom for MsgSbasRaw { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSbasRaw(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSbasRaw { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) } } -} -impl WireFormat for MsgSbasRaw { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[u8; 27] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.tow) - + WireFormat::len(&self.message_type) - + WireFormat::len(&self.data) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.message_type, buf); - WireFormat::write(&self.data, buf); + impl TryFrom for MsgSbasRaw { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSbasRaw(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSbasRaw { - sender_id: None, - sid: WireFormat::parse_unchecked(buf), - tow: WireFormat::parse_unchecked(buf), - message_type: WireFormat::parse_unchecked(buf), - data: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSbasRaw { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[u8; 27] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.tow) + + WireFormat::len(&self.message_type) + + WireFormat::len(&self.data) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.message_type, buf); + WireFormat::write(&self.data, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSbasRaw { + sender_id: None, + sid: WireFormat::parse_unchecked(buf), + tow: WireFormat::parse_unchecked(buf), + message_type: WireFormat::parse_unchecked(buf), + data: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/settings.rs b/rust/sbp/src/messages/settings.rs index 75ec03690a..190b0fe857 100644 --- a/rust/sbp/src/messages/settings.rs +++ b/rust/sbp/src/messages/settings.rs @@ -38,697 +38,924 @@ //! , the open source python command line utility for reading, writing, and //! saving settings in the piksi_tools repository on github as a helpful //! reference and example. - -use super::lib::*; - -/// Finished reading settings (host <= device) -/// -/// The settings message for indicating end of the settings values. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsReadByIndexDone { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} - -impl ConcreteMessage for MsgSettingsReadByIndexDone { - const MESSAGE_TYPE: u16 = 166; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_DONE"; -} - -impl SbpMessage for MsgSettingsReadByIndexDone { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub use msg_settings_read_by_index_done::MsgSettingsReadByIndexDone; +pub use msg_settings_read_by_index_req::MsgSettingsReadByIndexReq; +pub use msg_settings_read_by_index_resp::MsgSettingsReadByIndexResp; +pub use msg_settings_read_req::MsgSettingsReadReq; +pub use msg_settings_read_resp::MsgSettingsReadResp; +pub use msg_settings_register::MsgSettingsRegister; +pub use msg_settings_register_resp::MsgSettingsRegisterResp; +pub use msg_settings_save::MsgSettingsSave; +pub use msg_settings_write::MsgSettingsWrite; +pub use msg_settings_write_resp::MsgSettingsWriteResp; + +pub mod msg_settings_read_by_index_done { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Finished reading settings (host <= device) + /// + /// The settings message for indicating end of the settings values. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsReadByIndexDone { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + } + + impl ConcreteMessage for MsgSettingsReadByIndexDone { + const MESSAGE_TYPE: u16 = 166; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_DONE"; + } + + impl SbpMessage for MsgSettingsReadByIndexDone { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSettingsReadByIndexDone { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsReadByIndexDone(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSettingsReadByIndexDone { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsReadByIndexDone(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSettingsReadByIndexDone { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 - } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgSettingsReadByIndexDone { sender_id: None } + impl WireFormat for MsgSettingsReadByIndexDone { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgSettingsReadByIndexDone { sender_id: None } + } } } -/// Read setting by direct index (host => device) -/// -/// The settings message for iterating through the settings values. A device -/// will respond to this message with a "MSG_SETTINGS_READ_BY_INDEX_RESP". -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsReadByIndexReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// An index into the device settings, with values ranging from 0 to - /// length(settings). - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u16, -} +pub mod msg_settings_read_by_index_req { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSettingsReadByIndexReq { - const MESSAGE_TYPE: u16 = 162; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_REQ"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSettingsReadByIndexReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Read setting by direct index (host => device) + /// + /// The settings message for iterating through the settings values. A device + /// will respond to this message with a "MSG_SETTINGS_READ_BY_INDEX_RESP". + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsReadByIndexReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// An index into the device settings, with values ranging from 0 to + /// length(settings). + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u16, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSettingsReadByIndexReq { + const MESSAGE_TYPE: u16 = 162; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_REQ"; } -} -impl TryFrom for MsgSettingsReadByIndexReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsReadByIndexReq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSettingsReadByIndexReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsReadByIndexReq { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsReadByIndexReq { - sender_id: None, - index: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSettingsReadByIndexReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsReadByIndexReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} - -/// Read setting by direct index (host <= device) -/// -/// The settings message that reports the value of a setting at an index. -/// -/// In the string field, it reports NULL-terminated and delimited string with -/// contents "SECTION_SETTING\0SETTING\0VALUE\0FORMAT_TYPE\0". where the '\0' -/// escape sequence denotes the NULL character and where quotation marks are -/// omitted. The FORMAT_TYPE field is optional and denotes possible string -/// values of the setting as a hint to the user. If included, the format type -/// portion of the string has the format "enum:value1,value2,value3". An -/// example string that could be sent from the device is -/// "simulator\0enabled\0True\0enum:True,False\0". -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsReadByIndexResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// An index into the device settings, with values ranging from 0 to - /// length(settings) - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u16, - /// A NULL-terminated and delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE\0FORMAT_TYPE\0" - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, -} -impl ConcreteMessage for MsgSettingsReadByIndexResp { - const MESSAGE_TYPE: u16 = 167; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_RESP"; -} - -impl SbpMessage for MsgSettingsReadByIndexResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgSettingsReadByIndexReq { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsReadByIndexReq { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgSettingsReadByIndexResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsReadByIndexResp(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_settings_read_by_index_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Read setting by direct index (host <= device) + /// + /// The settings message that reports the value of a setting at an index. + /// + /// In the string field, it reports NULL-terminated and delimited string with + /// contents "SECTION_SETTING\0SETTING\0VALUE\0FORMAT_TYPE\0". where the '\0' + /// escape sequence denotes the NULL character and where quotation marks are + /// omitted. The FORMAT_TYPE field is optional and denotes possible string + /// values of the setting as a hint to the user. If included, the format type + /// portion of the string has the format "enum:value1,value2,value3". An + /// example string that could be sent from the device is + /// "simulator\0enabled\0True\0enum:True,False\0". + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsReadByIndexResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// An index into the device settings, with values ranging from 0 to + /// length(settings) + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u16, + /// A NULL-terminated and delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0FORMAT_TYPE\0" + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, + } + + impl ConcreteMessage for MsgSettingsReadByIndexResp { + const MESSAGE_TYPE: u16 = 167; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_BY_INDEX_RESP"; + } + + impl SbpMessage for MsgSettingsReadByIndexResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsReadByIndexResp { - const MIN_LEN: usize = - ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.index) + WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.index, buf); - WireFormat::write(&self.setting, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsReadByIndexResp { - sender_id: None, - index: WireFormat::parse_unchecked(buf), - setting: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSettingsReadByIndexResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsReadByIndexResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Read device configuration settings (host => device) -/// -/// The setting message that reads the device configuration. The string field -/// is a NULL-terminated and NULL-delimited string with contents -/// "SECTION_SETTING\0SETTING\0" where the '\0' escape sequence denotes the -/// NULL character and where quotation marks are omitted. An example string -/// that could be sent to a device is "solution\0soln_freq\0". A device will -/// only respond to this message when it is received from sender ID 0x42. A -/// device should respond with a MSG_SETTINGS_READ_RESP message (msg_id -/// 0x00A5). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsReadReq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// A NULL-terminated and NULL-delimited string with contents - /// "SECTION_SETTING\0SETTING\0" - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, -} - -impl ConcreteMessage for MsgSettingsReadReq { - const MESSAGE_TYPE: u16 = 164; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_REQ"; -} - -impl SbpMessage for MsgSettingsReadReq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + impl WireFormat for MsgSettingsReadByIndexResp { + const MIN_LEN: usize = + ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.index) + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.index, buf); + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsReadByIndexResp { + sender_id: None, + index: WireFormat::parse_unchecked(buf), + setting: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgSettingsReadReq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsReadReq(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_settings_read_req { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Read device configuration settings (host => device) + /// + /// The setting message that reads the device configuration. The string field + /// is a NULL-terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0" where the '\0' escape sequence denotes the + /// NULL character and where quotation marks are omitted. An example string + /// that could be sent to a device is "solution\0soln_freq\0". A device will + /// only respond to this message when it is received from sender ID 0x42. A + /// device should respond with a MSG_SETTINGS_READ_RESP message (msg_id + /// 0x00A5). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsReadReq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// A NULL-terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0" + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, + } + + impl ConcreteMessage for MsgSettingsReadReq { + const MESSAGE_TYPE: u16 = 164; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_REQ"; + } + + impl SbpMessage for MsgSettingsReadReq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsReadReq { - const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.setting, buf); + impl TryFrom for MsgSettingsReadReq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsReadReq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsReadReq { - sender_id: None, - setting: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSettingsReadReq { + const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsReadReq { + sender_id: None, + setting: WireFormat::parse_unchecked(buf), + } } } } -/// Read device configuration settings (host <= device) -/// -/// The setting message with which the device responds after a -/// MSG_SETTING_READ_REQ is sent to device. The string field is a NULL- -/// terminated and NULL-delimited string with contents -/// "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence denotes -/// the NULL character and where quotation marks are omitted. An example -/// string that could be sent from device is "solution\0soln_freq\010\0". -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsReadResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// A NULL-terminated and NULL-delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE\0" - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, -} +pub mod msg_settings_read_resp { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSettingsReadResp { - const MESSAGE_TYPE: u16 = 165; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_RESP"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSettingsReadResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Read device configuration settings (host <= device) + /// + /// The setting message with which the device responds after a + /// MSG_SETTING_READ_REQ is sent to device. The string field is a NULL- + /// terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence denotes + /// the NULL character and where quotation marks are omitted. An example + /// string that could be sent from device is "solution\0soln_freq\010\0". + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsReadResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// A NULL-terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0" + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSettingsReadResp { + const MESSAGE_TYPE: u16 = 165; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_READ_RESP"; } -} -impl TryFrom for MsgSettingsReadResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsReadResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSettingsReadResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsReadResp { - const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.setting, buf); + impl TryFrom for MsgSettingsReadResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsReadResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsReadResp { - sender_id: None, - setting: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSettingsReadResp { + const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsReadResp { + sender_id: None, + setting: WireFormat::parse_unchecked(buf), + } } } } -/// Register setting and default value (device => host) -/// -/// This message registers the presence and default value of a setting with a -/// settings daemon. The host should reply with MSG_SETTINGS_WRITE for this -/// setting to set the initial value. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsRegister { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// A NULL-terminated and delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE". - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, -} +pub mod msg_settings_register { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSettingsRegister { - const MESSAGE_TYPE: u16 = 174; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_REGISTER"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSettingsRegister { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Register setting and default value (device => host) + /// + /// This message registers the presence and default value of a setting with a + /// settings daemon. The host should reply with MSG_SETTINGS_WRITE for this + /// setting to set the initial value. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsRegister { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// A NULL-terminated and delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE". + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSettingsRegister { + const MESSAGE_TYPE: u16 = 174; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_REGISTER"; } -} -impl TryFrom for MsgSettingsRegister { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsRegister(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSettingsRegister { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsRegister { - const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.setting, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsRegister { - sender_id: None, - setting: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSettingsRegister { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsRegister(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Register setting and default value (device <= host) -/// -/// This message responds to setting registration with the effective value. -/// The effective value shall differ from the given default value if setting -/// was already registered or is available in the permanent setting storage -/// and had a different value. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsRegisterResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Register status - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: u8, - /// A NULL-terminated and delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE". The meaning of value is defined - /// according to the status field. - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, + impl WireFormat for MsgSettingsRegister { + const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsRegister { + sender_id: None, + setting: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgSettingsRegisterResp { - const MESSAGE_TYPE: u16 = 431; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_REGISTER_RESP"; -} +pub mod msg_settings_register_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Register setting and default value (device <= host) + /// + /// This message responds to setting registration with the effective value. + /// The effective value shall differ from the given default value if setting + /// was already registered or is available in the permanent setting storage + /// and had a different value. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsRegisterResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Register status + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: u8, + /// A NULL-terminated and delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE". The meaning of value is defined + /// according to the status field. + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, + } + + impl MsgSettingsRegisterResp { + /// Gets the [RegisterStatus][self::RegisterStatus] stored in the `status` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `RegisterStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `RegisterStatus` were added. + pub fn register_status(&self) -> Result { + get_bit_range!(self.status, u8, u8, 1, 0).try_into() + } -impl SbpMessage for MsgSettingsRegisterResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Set the bitrange corresponding to the [RegisterStatus][RegisterStatus] of the `status` bitfield. + pub fn set_register_status(&mut self, register_status: RegisterStatus) { + set_bit_range!(&mut self.status, register_status, u8, u8, 1, 0); + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgSettingsRegisterResp { + const MESSAGE_TYPE: u16 = 431; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_REGISTER_RESP"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgSettingsRegisterResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSettingsRegisterResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsRegisterResp(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSettingsRegisterResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsRegisterResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSettingsRegisterResp { - const MIN_LEN: usize = - ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.status) + WireFormat::len(&self.setting) + impl WireFormat for MsgSettingsRegisterResp { + const MIN_LEN: usize = + ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.status) + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.status, buf); + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsRegisterResp { + sender_id: None, + status: WireFormat::parse_unchecked(buf), + setting: WireFormat::parse_unchecked(buf), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.status, buf); - WireFormat::write(&self.setting, buf); + + /// Register status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum RegisterStatus { + /// Accepted; requested default value returned + AcceptedRequestedDefaultValueReturned = 0, + + /// Accepted; setting found in permanent storage, value from storage + /// returned + AcceptedSettingFoundInPermanentStorageValueFromStorageReturned = 1, + + /// Rejected; setting already registered, value from memory returned + RejectedSettingAlreadyRegisteredValueFromMemoryReturned = 2, + + /// Rejected; malformed message + RejectedMalformedMessage = 3, + } + + impl std::fmt::Display for RegisterStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RegisterStatus::AcceptedRequestedDefaultValueReturned => { + f.write_str("Accepted; requested default value returned") + } + RegisterStatus::AcceptedSettingFoundInPermanentStorageValueFromStorageReturned => f + .write_str( + "Accepted; setting found in permanent storage, value from storage returned", + ), + RegisterStatus::RejectedSettingAlreadyRegisteredValueFromMemoryReturned => { + f.write_str("Rejected; setting already registered, value from memory returned") + } + RegisterStatus::RejectedMalformedMessage => { + f.write_str("Rejected; malformed message") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsRegisterResp { - sender_id: None, - status: WireFormat::parse_unchecked(buf), - setting: WireFormat::parse_unchecked(buf), + + impl TryFrom for RegisterStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(RegisterStatus::AcceptedRequestedDefaultValueReturned), + 1 => Ok( + RegisterStatus::AcceptedSettingFoundInPermanentStorageValueFromStorageReturned, + ), + 2 => Ok(RegisterStatus::RejectedSettingAlreadyRegisteredValueFromMemoryReturned), + 3 => Ok(RegisterStatus::RejectedMalformedMessage), + i => Err(i), + } } } } -/// Save settings to flash (host => device) -/// -/// The save settings message persists the device's current settings -/// configuration to its onboard flash memory file system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsSave { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, -} +pub mod msg_settings_save { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSettingsSave { - const MESSAGE_TYPE: u16 = 161; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_SAVE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSettingsSave { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Save settings to flash (host => device) + /// + /// The save settings message persists the device's current settings + /// configuration to its onboard flash memory file system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsSave { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSettingsSave { + const MESSAGE_TYPE: u16 = 161; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_SAVE"; } -} -impl TryFrom for MsgSettingsSave { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsSave(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSettingsSave { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsSave { - const MIN_LEN: usize = 0; - fn len(&self) -> usize { - 0 + impl TryFrom for MsgSettingsSave { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsSave(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn write(&self, _buf: &mut B) {} - fn parse_unchecked(_buf: &mut B) -> Self { - MsgSettingsSave { sender_id: None } + + impl WireFormat for MsgSettingsSave { + const MIN_LEN: usize = 0; + fn len(&self) -> usize { + 0 + } + fn write(&self, _buf: &mut B) {} + fn parse_unchecked(_buf: &mut B) -> Self { + MsgSettingsSave { sender_id: None } + } } } -/// Write device configuration settings (host => device) -/// -/// The setting message writes the device configuration for a particular -/// setting via A NULL-terminated and NULL-delimited string with contents -/// "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence denotes -/// the NULL character and where quotation marks are omitted. A device will -/// only process to this message when it is received from sender ID 0x42. An -/// example string that could be sent to a device is -/// "solution\0soln_freq\010\0". -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsWrite { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// A NULL-terminated and NULL-delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE\0" - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, -} +pub mod msg_settings_write { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSettingsWrite { - const MESSAGE_TYPE: u16 = 160; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_WRITE"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSettingsWrite { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Write device configuration settings (host => device) + /// + /// The setting message writes the device configuration for a particular + /// setting via A NULL-terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence denotes + /// the NULL character and where quotation marks are omitted. A device will + /// only process to this message when it is received from sender ID 0x42. An + /// example string that could be sent to a device is + /// "solution\0soln_freq\010\0". + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsWrite { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// A NULL-terminated and NULL-delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0" + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSettingsWrite { + const MESSAGE_TYPE: u16 = 160; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_WRITE"; } -} -impl TryFrom for MsgSettingsWrite { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsWrite(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSettingsWrite { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSettingsWrite { - const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.setting, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsWrite { - sender_id: None, - setting: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSettingsWrite { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsWrite(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Acknowledgement with status of MSG_SETTINGS_WRITE -/// -/// Return the status of a write request with the new value of the setting. -/// If the requested value is rejected, the current value will be returned. -/// The string field is a NULL-terminated and NULL-delimited string with -/// contents "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape -/// sequence denotes the NULL character and where quotation marks are omitted. -/// An example string that could be sent from device is -/// "solution\0soln_freq\010\0". -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSettingsWriteResp { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Write status - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: u8, - /// A NULL-terminated and delimited string with contents - /// "SECTION_SETTING\0SETTING\0VALUE\0" - #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] - pub setting: SbpString, Multipart>, + impl WireFormat for MsgSettingsWrite { + const MIN_LEN: usize = , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsWrite { + sender_id: None, + setting: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgSettingsWriteResp { - const MESSAGE_TYPE: u16 = 175; - const MESSAGE_NAME: &'static str = "MSG_SETTINGS_WRITE_RESP"; -} +pub mod msg_settings_write_resp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Acknowledgement with status of MSG_SETTINGS_WRITE + /// + /// Return the status of a write request with the new value of the setting. + /// If the requested value is rejected, the current value will be returned. + /// The string field is a NULL-terminated and NULL-delimited string with + /// contents "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape + /// sequence denotes the NULL character and where quotation marks are omitted. + /// An example string that could be sent from device is + /// "solution\0soln_freq\010\0". + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSettingsWriteResp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Write status + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: u8, + /// A NULL-terminated and delimited string with contents + /// "SECTION_SETTING\0SETTING\0VALUE\0" + #[cfg_attr(feature = "serde", serde(rename(serialize = "setting")))] + pub setting: SbpString, Multipart>, + } + + impl MsgSettingsWriteResp { + /// Gets the [WriteStatus][self::WriteStatus] stored in the `status` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `WriteStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `WriteStatus` were added. + pub fn write_status(&self) -> Result { + get_bit_range!(self.status, u8, u8, 1, 0).try_into() + } -impl SbpMessage for MsgSettingsWriteResp { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Set the bitrange corresponding to the [WriteStatus][WriteStatus] of the `status` bitfield. + pub fn set_write_status(&mut self, write_status: WriteStatus) { + set_bit_range!(&mut self.status, write_status, u8, u8, 1, 0); + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgSettingsWriteResp { + const MESSAGE_TYPE: u16 = 175; + const MESSAGE_NAME: &'static str = "MSG_SETTINGS_WRITE_RESP"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgSettingsWriteResp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgSettingsWriteResp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSettingsWriteResp(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgSettingsWriteResp { + const MIN_LEN: usize = + ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.status) + WireFormat::len(&self.setting) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.status, buf); + WireFormat::write(&self.setting, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSettingsWriteResp { + sender_id: None, + status: WireFormat::parse_unchecked(buf), + setting: WireFormat::parse_unchecked(buf), + } + } } -} -impl TryFrom for MsgSettingsWriteResp { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSettingsWriteResp(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Write status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum WriteStatus { + /// Accepted; value updated + AcceptedValueUpdated = 0, + + /// Rejected; value unparsable or out-of-range + RejectedValueUnparsableOrOutOfRange = 1, + + /// Rejected; requested setting does not exist + RejectedRequestedSettingDoesNotExist = 2, + + /// Rejected; setting name could not be parsed + RejectedSettingNameCouldNotBeParsed = 3, + + /// Rejected; setting is read only + RejectedSettingIsReadOnly = 4, + + /// Rejected; modification is temporarily disabled + RejectedModificationIsTemporarilyDisabled = 5, + + /// Rejected; unspecified error + RejectedUnspecifiedError = 6, + } + + impl std::fmt::Display for WriteStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + WriteStatus::AcceptedValueUpdated => f.write_str("Accepted; value updated"), + WriteStatus::RejectedValueUnparsableOrOutOfRange => { + f.write_str("Rejected; value unparsable or out-of-range") + } + WriteStatus::RejectedRequestedSettingDoesNotExist => { + f.write_str("Rejected; requested setting does not exist") + } + WriteStatus::RejectedSettingNameCouldNotBeParsed => { + f.write_str("Rejected; setting name could not be parsed") + } + WriteStatus::RejectedSettingIsReadOnly => { + f.write_str("Rejected; setting is read only") + } + WriteStatus::RejectedModificationIsTemporarilyDisabled => { + f.write_str("Rejected; modification is temporarily disabled") + } + WriteStatus::RejectedUnspecifiedError => f.write_str("Rejected; unspecified error"), + } } } -} -impl WireFormat for MsgSettingsWriteResp { - const MIN_LEN: usize = - ::MIN_LEN + , Multipart> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.status) + WireFormat::len(&self.setting) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.status, buf); - WireFormat::write(&self.setting, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSettingsWriteResp { - sender_id: None, - status: WireFormat::parse_unchecked(buf), - setting: WireFormat::parse_unchecked(buf), + impl TryFrom for WriteStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(WriteStatus::AcceptedValueUpdated), + 1 => Ok(WriteStatus::RejectedValueUnparsableOrOutOfRange), + 2 => Ok(WriteStatus::RejectedRequestedSettingDoesNotExist), + 3 => Ok(WriteStatus::RejectedSettingNameCouldNotBeParsed), + 4 => Ok(WriteStatus::RejectedSettingIsReadOnly), + 5 => Ok(WriteStatus::RejectedModificationIsTemporarilyDisabled), + 6 => Ok(WriteStatus::RejectedUnspecifiedError), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/solution_meta.rs b/rust/sbp/src/messages/solution_meta.rs index 06dfb86a91..02a6810888 100644 --- a/rust/sbp/src/messages/solution_meta.rs +++ b/rust/sbp/src/messages/solution_meta.rs @@ -14,392 +14,1068 @@ //****************************************************************************/ //! Standardized Metadata messages for Fuzed Solution from Swift Navigation //! devices. +pub use gnss_input_type::GnssInputType; +pub use imu_input_type::ImuInputType; +pub use msg_soln_meta::MsgSolnMeta; +pub use msg_soln_meta_dep_a::MsgSolnMetaDepA; +pub use odo_input_type::OdoInputType; +pub use solution_input_type::SolutionInputType; -use super::lib::*; - -/// Instruments the physical type of GNSS sensor input to the fuzed solution -/// -/// Metadata around the GNSS sensors involved in the fuzed solution. -/// Accessible through sol_in\[N\].flags in a MSG_SOLN_META. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GnssInputType { - /// flags that store all relevant info specific to this sensor type. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod gnss_input_type { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; -impl WireFormat for GnssInputType { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) + /// Instruments the physical type of GNSS sensor input to the fuzed solution + /// + /// Metadata around the GNSS sensors involved in the fuzed solution. + /// Accessible through sol_in\[N\].flags in a MSG_SOLN_META. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GnssInputType { + /// flags that store all relevant info specific to this sensor type. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); + + impl GnssInputType { + /// Gets the [TypeOfGnssMeasurement][self::TypeOfGnssMeasurement] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeOfGnssMeasurement` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeOfGnssMeasurement` were added. + pub fn type_of_gnss_measurement(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TypeOfGnssMeasurement][TypeOfGnssMeasurement] of the `flags` bitfield. + pub fn set_type_of_gnss_measurement( + &mut self, + type_of_gnss_measurement: TypeOfGnssMeasurement, + ) { + set_bit_range!(&mut self.flags, type_of_gnss_measurement, u8, u8, 1, 0); + } } - fn parse_unchecked(buf: &mut B) -> Self { - GnssInputType { - flags: WireFormat::parse_unchecked(buf), + + impl WireFormat for GnssInputType { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GnssInputType { + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// Provides detail about the IMU sensor, its timestamping mode, and its quality for input to the fuzed solution - -/// -/// Metadata around the IMU sensors involved in the fuzed solution. Accessible -/// through sol_in\[N\].flags in a MSG_SOLN_META. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct ImuInputType { - /// Instrument time, grade, and architecture for a sensor. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// Type of GNSS measurement + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeOfGnssMeasurement { + /// GNSS Position + GnssPosition = 0, -impl WireFormat for ImuInputType { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) + /// GNSS Velocity Doppler + GnssVelocityDoppler = 1, + + /// GNSS Velocity Displacement + GnssVelocityDisplacement = 2, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); + + impl std::fmt::Display for TypeOfGnssMeasurement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeOfGnssMeasurement::GnssPosition => f.write_str("GNSS Position"), + TypeOfGnssMeasurement::GnssVelocityDoppler => f.write_str("GNSS Velocity Doppler"), + TypeOfGnssMeasurement::GnssVelocityDisplacement => { + f.write_str("GNSS Velocity Displacement") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - ImuInputType { - flags: WireFormat::parse_unchecked(buf), + + impl TryFrom for TypeOfGnssMeasurement { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeOfGnssMeasurement::GnssPosition), + 1 => Ok(TypeOfGnssMeasurement::GnssVelocityDoppler), + 2 => Ok(TypeOfGnssMeasurement::GnssVelocityDisplacement), + i => Err(i), + } } } } -/// Solution Sensors Metadata -/// -/// This message contains all metadata about the sensors received and/or used -/// in computing the sensorfusion solution. It focuses primarily, but not -/// only, on GNSS metadata. Regarding the age of the last received valid GNSS -/// solution, the highest two bits are time status, indicating whether age -/// gnss can or can not be used to retrieve time of measurement (noted TOM, -/// also known as time of validity) If it can, subtract 'age gnss' from 'tow' -/// in navigation messages to get TOM. Can be used before alignment is -/// complete in the Fusion Engine, when output solution is the last received -/// valid GNSS solution and its tow is not a TOM. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSolnMeta { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS time of week rounded to the nearest millisecond - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// Position Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] - pub pdop: u16, - /// Horizontal Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] - pub hdop: u16, - /// Vertical Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] - pub vdop: u16, - /// Age of corrections as per last available AGE_CORRECTIONS from PVT engine - /// (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "age_corrections")))] - pub age_corrections: u16, - /// Age and Time Status of the last received valid GNSS solution. - #[cfg_attr(feature = "serde", serde(rename(serialize = "age_gnss")))] - pub age_gnss: u32, - /// Array of Metadata describing the sensors potentially involved in the - /// solution. Each element in the array represents a single sensor type and - /// consists of flags containing (meta)data pertaining to that specific - /// single sensor. Refer to each (XX)InputType descriptor in the present - /// doc. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sol_in")))] - pub sol_in: Vec, -} +pub mod imu_input_type { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSolnMeta { - const MESSAGE_TYPE: u16 = 65294; - const MESSAGE_NAME: &'static str = "MSG_SOLN_META"; -} + use super::*; + use crate::messages::lib::*; + + /// Provides detail about the IMU sensor, its timestamping mode, and its quality for input to the fuzed solution -impl SbpMessage for MsgSolnMeta { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// + /// Metadata around the IMU sensors involved in the fuzed solution. Accessible + /// through sol_in\[N\].flags in a MSG_SOLN_META. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct ImuInputType { + /// Instrument time, grade, and architecture for a sensor. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ImuInputType { + /// Gets the [TimeStatus][self::TimeStatus] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeStatus` were added. + pub fn time_status(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 4).try_into() + } + + /// Set the bitrange corresponding to the [TimeStatus][TimeStatus] of the `flags` bitfield. + pub fn set_time_status(&mut self, time_status: TimeStatus) { + set_bit_range!(&mut self.flags, time_status, u8, u8, 5, 4); + } + + /// Gets the [ImuGrade][self::ImuGrade] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ImuGrade` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ImuGrade` were added. + pub fn imu_grade(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 2).try_into() + } + + /// Set the bitrange corresponding to the [ImuGrade][ImuGrade] of the `flags` bitfield. + pub fn set_imu_grade(&mut self, imu_grade: ImuGrade) { + set_bit_range!(&mut self.flags, imu_grade, u8, u8, 3, 2); + } + + /// Gets the [ImuArchitecture][self::ImuArchitecture] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ImuArchitecture` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ImuArchitecture` were added. + pub fn imu_architecture(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [ImuArchitecture][ImuArchitecture] of the `flags` bitfield. + pub fn set_imu_architecture(&mut self, imu_architecture: ImuArchitecture) { + set_bit_range!(&mut self.flags, imu_architecture, u8, u8, 1, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl WireFormat for ImuInputType { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + ImuInputType { + flags: WireFormat::parse_unchecked(buf), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Time status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeStatus { + /// Reference epoch is start of current GPS week + ReferenceEpochIsStartOfCurrentGpsWeek = 0, + + /// Reference epoch is time of system startup + ReferenceEpochIsTimeOfSystemStartup = 1, + + /// Reference epoch is unknown + ReferenceEpochIsUnknown = 2, + + /// Reference epoch is last PPS + ReferenceEpochIsLastPps = 3, + } + + impl std::fmt::Display for TimeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek => { + f.write_str("Reference epoch is start of current GPS week") + } + TimeStatus::ReferenceEpochIsTimeOfSystemStartup => { + f.write_str("Reference epoch is time of system startup") + } + TimeStatus::ReferenceEpochIsUnknown => f.write_str("Reference epoch is unknown"), + TimeStatus::ReferenceEpochIsLastPps => f.write_str("Reference epoch is last PPS"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TimeStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek), + 1 => Ok(TimeStatus::ReferenceEpochIsTimeOfSystemStartup), + 2 => Ok(TimeStatus::ReferenceEpochIsUnknown), + 3 => Ok(TimeStatus::ReferenceEpochIsLastPps), + i => Err(i), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + /// IMU Grade + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ImuGrade { + /// Consumer Grade + ConsumerGrade = 0, + + /// Tactical grade + TacticalGrade = 1, + + /// Intermediate Grade + IntermediateGrade = 2, + + /// Superior (Marine / Aviation) Grade + SuperiorGrade = 3, } -} -impl TryFrom for MsgSolnMeta { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSolnMeta(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for ImuGrade { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ImuGrade::ConsumerGrade => f.write_str("Consumer Grade"), + ImuGrade::TacticalGrade => f.write_str("Tactical grade"), + ImuGrade::IntermediateGrade => f.write_str("Intermediate Grade"), + ImuGrade::SuperiorGrade => f.write_str("Superior (Marine / Aviation) Grade"), + } } } -} -impl WireFormat for MsgSolnMeta { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.pdop) - + WireFormat::len(&self.hdop) - + WireFormat::len(&self.vdop) - + WireFormat::len(&self.age_corrections) - + WireFormat::len(&self.age_gnss) - + WireFormat::len(&self.sol_in) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.pdop, buf); - WireFormat::write(&self.hdop, buf); - WireFormat::write(&self.vdop, buf); - WireFormat::write(&self.age_corrections, buf); - WireFormat::write(&self.age_gnss, buf); - WireFormat::write(&self.sol_in, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSolnMeta { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - pdop: WireFormat::parse_unchecked(buf), - hdop: WireFormat::parse_unchecked(buf), - vdop: WireFormat::parse_unchecked(buf), - age_corrections: WireFormat::parse_unchecked(buf), - age_gnss: WireFormat::parse_unchecked(buf), - sol_in: WireFormat::parse_unchecked(buf), + impl TryFrom for ImuGrade { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ImuGrade::ConsumerGrade), + 1 => Ok(ImuGrade::TacticalGrade), + 2 => Ok(ImuGrade::IntermediateGrade), + 3 => Ok(ImuGrade::SuperiorGrade), + i => Err(i), + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -/// This message contains all metadata about the sensors received and/or used -/// in computing the Fuzed Solution. It focuses primarily, but not only, on -/// GNSS metadata. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSolnMetaDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Position Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] - pub pdop: u16, - /// Horizontal Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] - pub hdop: u16, - /// Vertical Dilution of Precision as per last available DOPS from PVT - /// engine (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] - pub vdop: u16, - /// Number of satellites as per last available solution from PVT engine - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] - pub n_sats: u8, - /// Age of corrections as per last available AGE_CORRECTIONS from PVT engine - /// (0xFFFF indicates invalid) - #[cfg_attr(feature = "serde", serde(rename(serialize = "age_corrections")))] - pub age_corrections: u16, - /// State of alignment and the status and receipt of the alignment inputs - #[cfg_attr(feature = "serde", serde(rename(serialize = "alignment_status")))] - pub alignment_status: u8, - /// Tow of last-used GNSS position measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "last_used_gnss_pos_tow")))] - pub last_used_gnss_pos_tow: u32, - /// Tow of last-used GNSS velocity measurement - #[cfg_attr(feature = "serde", serde(rename(serialize = "last_used_gnss_vel_tow")))] - pub last_used_gnss_vel_tow: u32, - /// Array of Metadata describing the sensors potentially involved in the - /// solution. Each element in the array represents a single sensor type and - /// consists of flags containing (meta)data pertaining to that specific - /// single sensor. Refer to each (XX)InputType descriptor in the present - /// doc. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sol_in")))] - pub sol_in: Vec, -} + /// IMU architecture + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ImuArchitecture { + /// 6-axis MEMS + _6AxisMems = 0, + + /// Other type + OtherType = 1, + } -impl ConcreteMessage for MsgSolnMetaDepA { - const MESSAGE_TYPE: u16 = 65295; - const MESSAGE_NAME: &'static str = "MSG_SOLN_META_DEP_A"; + impl std::fmt::Display for ImuArchitecture { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ImuArchitecture::_6AxisMems => f.write_str("6-axis MEMS"), + ImuArchitecture::OtherType => f.write_str("Other type"), + } + } + } + + impl TryFrom for ImuArchitecture { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ImuArchitecture::_6AxisMems), + 1 => Ok(ImuArchitecture::OtherType), + i => Err(i), + } + } + } } -impl SbpMessage for MsgSolnMetaDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_soln_meta { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Solution Sensors Metadata + /// + /// This message contains all metadata about the sensors received and/or used + /// in computing the sensorfusion solution. It focuses primarily, but not + /// only, on GNSS metadata. Regarding the age of the last received valid GNSS + /// solution, the highest two bits are time status, indicating whether age + /// gnss can or can not be used to retrieve time of measurement (noted TOM, + /// also known as time of validity) If it can, subtract 'age gnss' from 'tow' + /// in navigation messages to get TOM. Can be used before alignment is + /// complete in the Fusion Engine, when output solution is the last received + /// valid GNSS solution and its tow is not a TOM. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSolnMeta { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS time of week rounded to the nearest millisecond + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// Position Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] + pub pdop: u16, + /// Horizontal Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] + pub hdop: u16, + /// Vertical Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] + pub vdop: u16, + /// Age of corrections as per last available AGE_CORRECTIONS from PVT engine + /// (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "age_corrections")))] + pub age_corrections: u16, + /// Age and Time Status of the last received valid GNSS solution. + #[cfg_attr(feature = "serde", serde(rename(serialize = "age_gnss")))] + pub age_gnss: u32, + /// Array of Metadata describing the sensors potentially involved in the + /// solution. Each element in the array represents a single sensor type and + /// consists of flags containing (meta)data pertaining to that specific + /// single sensor. Refer to each (XX)InputType descriptor in the present + /// doc. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sol_in")))] + pub sol_in: Vec, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgSolnMeta { + /// Gets the [TimeStatus][self::TimeStatus] stored in the `age_gnss` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeStatus` were added. + pub fn time_status(&self) -> Result { + get_bit_range!(self.age_gnss, u32, u8, 31, 30).try_into() + } + + /// Set the bitrange corresponding to the [TimeStatus][TimeStatus] of the `age_gnss` bitfield. + pub fn set_time_status(&mut self, time_status: TimeStatus) { + set_bit_range!(&mut self.age_gnss, time_status, u32, u8, 31, 30); + } + + /// Gets the `age_of_the_last_received_valid_gnss_solution` stored in `age_gnss`. + pub fn age_of_the_last_received_valid_gnss_solution(&self) -> u32 { + get_bit_range!(self.age_gnss, u32, u32, 29, 0) + } + + /// Sets the `age_of_the_last_received_valid_gnss_solution` bitrange of `age_gnss`. + pub fn set_age_of_the_last_received_valid_gnss_solution( + &mut self, + age_of_the_last_received_valid_gnss_solution: u32, + ) { + set_bit_range!( + &mut self.age_gnss, + age_of_the_last_received_valid_gnss_solution, + u32, + u32, + 29, + 0 + ); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgSolnMeta { + const MESSAGE_TYPE: u16 = 65294; + const MESSAGE_NAME: &'static str = "MSG_SOLN_META"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgSolnMeta { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgSolnMeta { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSolnMeta(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgSolnMetaDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSolnMetaDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgSolnMeta { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.pdop) + + WireFormat::len(&self.hdop) + + WireFormat::len(&self.vdop) + + WireFormat::len(&self.age_corrections) + + WireFormat::len(&self.age_gnss) + + WireFormat::len(&self.sol_in) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.pdop, buf); + WireFormat::write(&self.hdop, buf); + WireFormat::write(&self.vdop, buf); + WireFormat::write(&self.age_corrections, buf); + WireFormat::write(&self.age_gnss, buf); + WireFormat::write(&self.sol_in, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSolnMeta { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + pdop: WireFormat::parse_unchecked(buf), + hdop: WireFormat::parse_unchecked(buf), + vdop: WireFormat::parse_unchecked(buf), + age_corrections: WireFormat::parse_unchecked(buf), + age_gnss: WireFormat::parse_unchecked(buf), + sol_in: WireFormat::parse_unchecked(buf), + } } } -} -impl WireFormat for MsgSolnMetaDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.pdop) - + WireFormat::len(&self.hdop) - + WireFormat::len(&self.vdop) - + WireFormat::len(&self.n_sats) - + WireFormat::len(&self.age_corrections) - + WireFormat::len(&self.alignment_status) - + WireFormat::len(&self.last_used_gnss_pos_tow) - + WireFormat::len(&self.last_used_gnss_vel_tow) - + WireFormat::len(&self.sol_in) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.pdop, buf); - WireFormat::write(&self.hdop, buf); - WireFormat::write(&self.vdop, buf); - WireFormat::write(&self.n_sats, buf); - WireFormat::write(&self.age_corrections, buf); - WireFormat::write(&self.alignment_status, buf); - WireFormat::write(&self.last_used_gnss_pos_tow, buf); - WireFormat::write(&self.last_used_gnss_vel_tow, buf); - WireFormat::write(&self.sol_in, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSolnMetaDepA { - sender_id: None, - pdop: WireFormat::parse_unchecked(buf), - hdop: WireFormat::parse_unchecked(buf), - vdop: WireFormat::parse_unchecked(buf), - n_sats: WireFormat::parse_unchecked(buf), - age_corrections: WireFormat::parse_unchecked(buf), - alignment_status: WireFormat::parse_unchecked(buf), - last_used_gnss_pos_tow: WireFormat::parse_unchecked(buf), - last_used_gnss_vel_tow: WireFormat::parse_unchecked(buf), - sol_in: WireFormat::parse_unchecked(buf), + /// Time status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeStatus { + /// Age can not be used to retrieve TOM + AgeCanNotBeUsedToRetrieveTom = 0, + + /// Age can be used to retrieve TOM + AgeCanBeUsedToRetrieveTom = 1, + } + + impl std::fmt::Display for TimeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeStatus::AgeCanNotBeUsedToRetrieveTom => { + f.write_str("Age can not be used to retrieve TOM") + } + TimeStatus::AgeCanBeUsedToRetrieveTom => { + f.write_str("Age can be used to retrieve TOM") + } + } } } -} -/// Provides detail about the Odometry sensor, its timestamping mode, and its quality for input to the fuzed solution - -/// -/// Metadata around the Odometry sensors involved in the fuzed solution. -/// Accessible through sol_in\[N\].flags in a MSG_SOLN_META. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct OdoInputType { - /// Instrument ODO rate, grade, and quality. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, + impl TryFrom for TimeStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeStatus::AgeCanNotBeUsedToRetrieveTom), + 1 => Ok(TimeStatus::AgeCanBeUsedToRetrieveTom), + i => Err(i), + } + } + } } -impl WireFormat for OdoInputType { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) +pub mod msg_soln_meta_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + /// This message contains all metadata about the sensors received and/or used + /// in computing the Fuzed Solution. It focuses primarily, but not only, on + /// GNSS metadata. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSolnMetaDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Position Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "pdop")))] + pub pdop: u16, + /// Horizontal Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "hdop")))] + pub hdop: u16, + /// Vertical Dilution of Precision as per last available DOPS from PVT + /// engine (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "vdop")))] + pub vdop: u16, + /// Number of satellites as per last available solution from PVT engine + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_sats")))] + pub n_sats: u8, + /// Age of corrections as per last available AGE_CORRECTIONS from PVT engine + /// (0xFFFF indicates invalid) + #[cfg_attr(feature = "serde", serde(rename(serialize = "age_corrections")))] + pub age_corrections: u16, + /// State of alignment and the status and receipt of the alignment inputs + #[cfg_attr(feature = "serde", serde(rename(serialize = "alignment_status")))] + pub alignment_status: u8, + /// Tow of last-used GNSS position measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "last_used_gnss_pos_tow")))] + pub last_used_gnss_pos_tow: u32, + /// Tow of last-used GNSS velocity measurement + #[cfg_attr(feature = "serde", serde(rename(serialize = "last_used_gnss_vel_tow")))] + pub last_used_gnss_vel_tow: u32, + /// Array of Metadata describing the sensors potentially involved in the + /// solution. Each element in the array represents a single sensor type and + /// consists of flags containing (meta)data pertaining to that specific + /// single sensor. Refer to each (XX)InputType descriptor in the present + /// doc. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sol_in")))] + pub sol_in: Vec, + } + + impl MsgSolnMetaDepA { + /// Gets the [AlignmentStatus][self::AlignmentStatus] stored in the `alignment_status` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AlignmentStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AlignmentStatus` were added. + pub fn alignment_status(&self) -> Result { + get_bit_range!(self.alignment_status, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [AlignmentStatus][AlignmentStatus] of the `alignment_status` bitfield. + pub fn set_alignment_status(&mut self, alignment_status: AlignmentStatus) { + set_bit_range!(&mut self.alignment_status, alignment_status, u8, u8, 2, 0); + } + } + + impl ConcreteMessage for MsgSolnMetaDepA { + const MESSAGE_TYPE: u16 = 65295; + const MESSAGE_NAME: &'static str = "MSG_SOLN_META_DEP_A"; + } + + impl SbpMessage for MsgSolnMetaDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgSolnMetaDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSolnMetaDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgSolnMetaDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.pdop) + + WireFormat::len(&self.hdop) + + WireFormat::len(&self.vdop) + + WireFormat::len(&self.n_sats) + + WireFormat::len(&self.age_corrections) + + WireFormat::len(&self.alignment_status) + + WireFormat::len(&self.last_used_gnss_pos_tow) + + WireFormat::len(&self.last_used_gnss_vel_tow) + + WireFormat::len(&self.sol_in) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.pdop, buf); + WireFormat::write(&self.hdop, buf); + WireFormat::write(&self.vdop, buf); + WireFormat::write(&self.n_sats, buf); + WireFormat::write(&self.age_corrections, buf); + WireFormat::write(&self.alignment_status, buf); + WireFormat::write(&self.last_used_gnss_pos_tow, buf); + WireFormat::write(&self.last_used_gnss_vel_tow, buf); + WireFormat::write(&self.sol_in, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSolnMetaDepA { + sender_id: None, + pdop: WireFormat::parse_unchecked(buf), + hdop: WireFormat::parse_unchecked(buf), + vdop: WireFormat::parse_unchecked(buf), + n_sats: WireFormat::parse_unchecked(buf), + age_corrections: WireFormat::parse_unchecked(buf), + alignment_status: WireFormat::parse_unchecked(buf), + last_used_gnss_pos_tow: WireFormat::parse_unchecked(buf), + last_used_gnss_vel_tow: WireFormat::parse_unchecked(buf), + sol_in: WireFormat::parse_unchecked(buf), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); + + /// Alignment status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AlignmentStatus { + /// Unknown reason or already aligned + UnknownReasonOrAlreadyAligned = 0, + + /// Seed values loaded and Alignment in progress + SeedValuesLoadedAndAlignmentInProgress = 1, + + /// No seed values and Alignment in progress + NoSeedValuesAndAlignmentInProgress = 2, + + /// Seed values loaded but no GNSS measurements + SeedValuesLoadedButNoGnssMeasurements = 3, + + /// No seed values nor GNSS measurements + NoSeedValuesNorGnssMeasurements = 4, } - fn parse_unchecked(buf: &mut B) -> Self { - OdoInputType { - flags: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for AlignmentStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AlignmentStatus::UnknownReasonOrAlreadyAligned => { + f.write_str("Unknown reason or already aligned") + } + AlignmentStatus::SeedValuesLoadedAndAlignmentInProgress => { + f.write_str("Seed values loaded and Alignment in progress") + } + AlignmentStatus::NoSeedValuesAndAlignmentInProgress => { + f.write_str("No seed values and Alignment in progress") + } + AlignmentStatus::SeedValuesLoadedButNoGnssMeasurements => { + f.write_str("Seed values loaded but no GNSS measurements") + } + AlignmentStatus::NoSeedValuesNorGnssMeasurements => { + f.write_str("No seed values nor GNSS measurements") + } + } + } + } + + impl TryFrom for AlignmentStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AlignmentStatus::UnknownReasonOrAlreadyAligned), + 1 => Ok(AlignmentStatus::SeedValuesLoadedAndAlignmentInProgress), + 2 => Ok(AlignmentStatus::NoSeedValuesAndAlignmentInProgress), + 3 => Ok(AlignmentStatus::SeedValuesLoadedButNoGnssMeasurements), + 4 => Ok(AlignmentStatus::NoSeedValuesNorGnssMeasurements), + i => Err(i), + } } } } -/// Flags for a given solution input type -/// -/// Metadata describing which sensors were involved in the solution. The -/// structure is fixed no matter what the actual sensor type is. The -/// sensor_type field tells you which sensor we are talking about. It also -/// tells you whether the sensor data was actually used or not. The flags -/// field, always a u8, contains the sensor-specific data. The content of -/// flags, for each sensor type, is described in the relevant structures in -/// this section. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct SolutionInputType { - /// The type of sensor - #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_type")))] - pub sensor_type: u8, - /// Refer to each InputType description - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, +pub mod odo_input_type { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Provides detail about the Odometry sensor, its timestamping mode, and its quality for input to the fuzed solution + + /// + /// Metadata around the Odometry sensors involved in the fuzed solution. + /// Accessible through sol_in\[N\].flags in a MSG_SOLN_META. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct OdoInputType { + /// Instrument ODO rate, grade, and quality. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl OdoInputType { + /// Gets the [Rate][self::Rate] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Rate` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `Rate` were added. + pub fn rate(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 5, 4).try_into() + } + + /// Set the bitrange corresponding to the [Rate][Rate] of the `flags` bitfield. + pub fn set_rate(&mut self, rate: Rate) { + set_bit_range!(&mut self.flags, rate, u8, u8, 5, 4); + } + + /// Gets the [OdometerGrade][self::OdometerGrade] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `OdometerGrade` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `OdometerGrade` were added. + pub fn odometer_grade(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 2).try_into() + } + + /// Set the bitrange corresponding to the [OdometerGrade][OdometerGrade] of the `flags` bitfield. + pub fn set_odometer_grade(&mut self, odometer_grade: OdometerGrade) { + set_bit_range!(&mut self.flags, odometer_grade, u8, u8, 3, 2); + } + + /// Gets the [OdometerClass][self::OdometerClass] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `OdometerClass` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `OdometerClass` were added. + pub fn odometer_class(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [OdometerClass][OdometerClass] of the `flags` bitfield. + pub fn set_odometer_class(&mut self, odometer_class: OdometerClass) { + set_bit_range!(&mut self.flags, odometer_class, u8, u8, 1, 0); + } + } + + impl WireFormat for OdoInputType { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + OdoInputType { + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Rate + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Rate { + /// Fixed incoming rate + FixedIncomingRate = 0, + + /// Triggered by minimum distance or speed + TriggeredByMinimumDistanceOrSpeed = 1, + } + + impl std::fmt::Display for Rate { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Rate::FixedIncomingRate => f.write_str("Fixed incoming rate"), + Rate::TriggeredByMinimumDistanceOrSpeed => { + f.write_str("Triggered by minimum distance or speed") + } + } + } + } + + impl TryFrom for Rate { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(Rate::FixedIncomingRate), + 1 => Ok(Rate::TriggeredByMinimumDistanceOrSpeed), + i => Err(i), + } + } + } + + /// Odometer grade + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum OdometerGrade { + /// Low Grade (e.g. quantized CAN) + LowGrade = 0, + + /// Medium Grade + MediumGrade = 1, + + /// Superior Grade + SuperiorGrade = 2, + } + + impl std::fmt::Display for OdometerGrade { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OdometerGrade::LowGrade => f.write_str("Low Grade (e.g. quantized CAN)"), + OdometerGrade::MediumGrade => f.write_str("Medium Grade"), + OdometerGrade::SuperiorGrade => f.write_str("Superior Grade"), + } + } + } + + impl TryFrom for OdometerGrade { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(OdometerGrade::LowGrade), + 1 => Ok(OdometerGrade::MediumGrade), + 2 => Ok(OdometerGrade::SuperiorGrade), + i => Err(i), + } + } + } + + /// Odometer class + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum OdometerClass { + /// Single or averaged ticks + SingleOrAveragedTicks = 0, + + /// Single or averaged speed + SingleOrAveragedSpeed = 1, + + /// Multi-dimensional ticks + MultiDimensionalTicks = 2, + + /// Multi-dimensional speed + MultiDimensionalSpeed = 3, + } + + impl std::fmt::Display for OdometerClass { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OdometerClass::SingleOrAveragedTicks => f.write_str("Single or averaged ticks"), + OdometerClass::SingleOrAveragedSpeed => f.write_str("Single or averaged speed"), + OdometerClass::MultiDimensionalTicks => f.write_str("Multi-dimensional ticks"), + OdometerClass::MultiDimensionalSpeed => f.write_str("Multi-dimensional speed"), + } + } + } + + impl TryFrom for OdometerClass { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(OdometerClass::SingleOrAveragedTicks), + 1 => Ok(OdometerClass::SingleOrAveragedSpeed), + 2 => Ok(OdometerClass::MultiDimensionalTicks), + 3 => Ok(OdometerClass::MultiDimensionalSpeed), + i => Err(i), + } + } + } } -impl WireFormat for SolutionInputType { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sensor_type) + WireFormat::len(&self.flags) +pub mod solution_input_type { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Flags for a given solution input type + /// + /// Metadata describing which sensors were involved in the solution. The + /// structure is fixed no matter what the actual sensor type is. The + /// sensor_type field tells you which sensor we are talking about. It also + /// tells you whether the sensor data was actually used or not. The flags + /// field, always a u8, contains the sensor-specific data. The content of + /// flags, for each sensor type, is described in the relevant structures in + /// this section. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct SolutionInputType { + /// The type of sensor + #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_type")))] + pub sensor_type: u8, + /// Refer to each InputType description + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl SolutionInputType { + /// Gets the [SensorUsage][self::SensorUsage] stored in the `sensor_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SensorUsage` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SensorUsage` were added. + pub fn sensor_usage(&self) -> Result { + get_bit_range!(self.sensor_type, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [SensorUsage][SensorUsage] of the `sensor_type` bitfield. + pub fn set_sensor_usage(&mut self, sensor_usage: SensorUsage) { + set_bit_range!(&mut self.sensor_type, sensor_usage, u8, u8, 4, 3); + } + + /// Gets the [SensorType][self::SensorType] stored in the `sensor_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SensorType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SensorType` were added. + pub fn sensor_type(&self) -> Result { + get_bit_range!(self.sensor_type, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [SensorType][SensorType] of the `sensor_type` bitfield. + pub fn set_sensor_type(&mut self, sensor_type: SensorType) { + set_bit_range!(&mut self.sensor_type, sensor_type, u8, u8, 2, 0); + } + } + + impl WireFormat for SolutionInputType { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sensor_type) + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sensor_type, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + SolutionInputType { + sensor_type: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Sensor Usage + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SensorUsage { + /// Unknown + Unknown = 0, + + /// Received and used + ReceivedAndUsed = 1, + + /// Received but not used + ReceivedButNotUsed = 2, + } + + impl std::fmt::Display for SensorUsage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SensorUsage::Unknown => f.write_str("Unknown"), + SensorUsage::ReceivedAndUsed => f.write_str("Received and used"), + SensorUsage::ReceivedButNotUsed => f.write_str("Received but not used"), + } + } + } + + impl TryFrom for SensorUsage { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SensorUsage::Unknown), + 1 => Ok(SensorUsage::ReceivedAndUsed), + 2 => Ok(SensorUsage::ReceivedButNotUsed), + i => Err(i), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sensor_type, buf); - WireFormat::write(&self.flags, buf); + + /// Sensor Type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SensorType { + /// Invalid + Invalid = 0, + + /// GNSS Position (see GNSSInputType) + GnssPosition = 1, + + /// GNSS Velocity Displacement (see GNSSInputType) + GnssVelocityDisplacement = 2, + + /// GNSS Velocity Doppler (see GNSSInputType) + GnssVelocityDoppler = 3, + + /// Odometry Ticks (see OdoInputType) + OdometryTicks = 4, + + /// Odometry Speed (see OdoInputType) + OdometrySpeed = 5, + + /// IMU Sensor (see IMUInputType) + ImuSensor = 6, + } + + impl std::fmt::Display for SensorType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SensorType::Invalid => f.write_str("Invalid"), + SensorType::GnssPosition => f.write_str("GNSS Position (see GNSSInputType)"), + SensorType::GnssVelocityDisplacement => { + f.write_str("GNSS Velocity Displacement (see GNSSInputType)") + } + SensorType::GnssVelocityDoppler => { + f.write_str("GNSS Velocity Doppler (see GNSSInputType)") + } + SensorType::OdometryTicks => f.write_str("Odometry Ticks (see OdoInputType)"), + SensorType::OdometrySpeed => f.write_str("Odometry Speed (see OdoInputType)"), + SensorType::ImuSensor => f.write_str("IMU Sensor (see IMUInputType)"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - SolutionInputType { - sensor_type: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + + impl TryFrom for SensorType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SensorType::Invalid), + 1 => Ok(SensorType::GnssPosition), + 2 => Ok(SensorType::GnssVelocityDisplacement), + 3 => Ok(SensorType::GnssVelocityDoppler), + 4 => Ok(SensorType::OdometryTicks), + 5 => Ok(SensorType::OdometrySpeed), + 6 => Ok(SensorType::ImuSensor), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/ssr.rs b/rust/sbp/src/messages/ssr.rs index 42f23aad63..7999b09fce 100644 --- a/rust/sbp/src/messages/ssr.rs +++ b/rust/sbp/src/messages/ssr.rs @@ -13,1914 +13,2269 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Precise State Space Representation (SSR) corrections format - -use super::gnss::*; - -use super::lib::*; - -/// SSR code biases corrections for a particular satellite -/// -/// Code biases are to be added to pseudorange. The corrections conform with -/// RTCMv3 MT 1059 / 1065. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct CodeBiasesContent { - /// Signal encoded following RTCM specifications (DF380, DF381, DF382 and - /// DF467). - #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] - pub code: u8, - /// Code bias value - #[cfg_attr(feature = "serde", serde(rename(serialize = "value")))] - pub value: i16, -} - -impl WireFormat for CodeBiasesContent { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.code) + WireFormat::len(&self.value) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.code, buf); - WireFormat::write(&self.value, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - CodeBiasesContent { - code: WireFormat::parse_unchecked(buf), - value: WireFormat::parse_unchecked(buf), +pub use code_biases_content::CodeBiasesContent; +pub use grid_definition_header_dep_a::GridDefinitionHeaderDepA; +pub use gridded_correction_header::GriddedCorrectionHeader; +pub use gridded_correction_header_dep_a::GriddedCorrectionHeaderDepA; +pub use msg_ssr_code_biases::MsgSsrCodeBiases; +pub use msg_ssr_grid_definition_dep_a::MsgSsrGridDefinitionDepA; +pub use msg_ssr_gridded_correction::MsgSsrGriddedCorrection; +pub use msg_ssr_gridded_correction_dep_a::MsgSsrGriddedCorrectionDepA; +pub use msg_ssr_gridded_correction_no_std_dep_a::MsgSsrGriddedCorrectionNoStdDepA; +pub use msg_ssr_orbit_clock::MsgSsrOrbitClock; +pub use msg_ssr_orbit_clock_dep_a::MsgSsrOrbitClockDepA; +pub use msg_ssr_phase_biases::MsgSsrPhaseBiases; +pub use msg_ssr_satellite_apc::MsgSsrSatelliteApc; +pub use msg_ssr_stec_correction::MsgSsrStecCorrection; +pub use msg_ssr_stec_correction_dep_a::MsgSsrStecCorrectionDepA; +pub use msg_ssr_tile_definition::MsgSsrTileDefinition; +pub use phase_biases_content::PhaseBiasesContent; +pub use satellite_apc::SatelliteAPC; +pub use stec_header::STECHeader; +pub use stec_header_dep_a::STECHeaderDepA; +pub use stec_residual::STECResidual; +pub use stec_residual_no_std::STECResidualNoStd; +pub use stec_sat_element::STECSatElement; +pub use tropospheric_delay_correction::TroposphericDelayCorrection; +pub use tropospheric_delay_correction_no_std::TroposphericDelayCorrectionNoStd; + +pub mod code_biases_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// SSR code biases corrections for a particular satellite + /// + /// Code biases are to be added to pseudorange. The corrections conform with + /// RTCMv3 MT 1059 / 1065. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct CodeBiasesContent { + /// Signal encoded following RTCM specifications (DF380, DF381, DF382 and + /// DF467). + #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] + pub code: u8, + /// Code bias value + #[cfg_attr(feature = "serde", serde(rename(serialize = "value")))] + pub value: i16, + } + + impl WireFormat for CodeBiasesContent { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.code) + WireFormat::len(&self.value) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.code, buf); + WireFormat::write(&self.value, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + CodeBiasesContent { + code: WireFormat::parse_unchecked(buf), + value: WireFormat::parse_unchecked(buf), + } } } } -/// Defines the grid for MSG_SSR_GRIDDED_CORRECTION messages -/// -/// Defines the grid for MSG_SSR_GRIDDED_CORRECTION messages. Also includes an -/// RLE encoded validity list. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GridDefinitionHeaderDepA { - /// region_size (deg) = 10 / region_size_inverse 0 is an invalid value. - #[cfg_attr(feature = "serde", serde(rename(serialize = "region_size_inverse")))] - pub region_size_inverse: u8, - /// grid height (deg) = grid width (deg) = area_width / region_size 0 is an - /// invalid value. - #[cfg_attr(feature = "serde", serde(rename(serialize = "area_width")))] - pub area_width: u16, - /// North-West corner latitude (deg) = region_size * lat_nw_corner_enc - 90 - #[cfg_attr(feature = "serde", serde(rename(serialize = "lat_nw_corner_enc")))] - pub lat_nw_corner_enc: u16, - /// North-West corner longitude (deg) = region_size * lon_nw_corner_enc - - /// 180 - #[cfg_attr(feature = "serde", serde(rename(serialize = "lon_nw_corner_enc")))] - pub lon_nw_corner_enc: u16, - /// Number of messages in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] - pub num_msgs: u8, - /// Position of this message in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] - pub seq_num: u8, -} +pub mod grid_definition_header_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl WireFormat for GridDefinitionHeaderDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.region_size_inverse) - + WireFormat::len(&self.area_width) - + WireFormat::len(&self.lat_nw_corner_enc) - + WireFormat::len(&self.lon_nw_corner_enc) - + WireFormat::len(&self.num_msgs) - + WireFormat::len(&self.seq_num) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.region_size_inverse, buf); - WireFormat::write(&self.area_width, buf); - WireFormat::write(&self.lat_nw_corner_enc, buf); - WireFormat::write(&self.lon_nw_corner_enc, buf); - WireFormat::write(&self.num_msgs, buf); - WireFormat::write(&self.seq_num, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - GridDefinitionHeaderDepA { - region_size_inverse: WireFormat::parse_unchecked(buf), - area_width: WireFormat::parse_unchecked(buf), - lat_nw_corner_enc: WireFormat::parse_unchecked(buf), - lon_nw_corner_enc: WireFormat::parse_unchecked(buf), - num_msgs: WireFormat::parse_unchecked(buf), - seq_num: WireFormat::parse_unchecked(buf), + /// Defines the grid for MSG_SSR_GRIDDED_CORRECTION messages + /// + /// Defines the grid for MSG_SSR_GRIDDED_CORRECTION messages. Also includes an + /// RLE encoded validity list. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GridDefinitionHeaderDepA { + /// region_size (deg) = 10 / region_size_inverse 0 is an invalid value. + #[cfg_attr(feature = "serde", serde(rename(serialize = "region_size_inverse")))] + pub region_size_inverse: u8, + /// grid height (deg) = grid width (deg) = area_width / region_size 0 is an + /// invalid value. + #[cfg_attr(feature = "serde", serde(rename(serialize = "area_width")))] + pub area_width: u16, + /// North-West corner latitude (deg) = region_size * lat_nw_corner_enc - 90 + #[cfg_attr(feature = "serde", serde(rename(serialize = "lat_nw_corner_enc")))] + pub lat_nw_corner_enc: u16, + /// North-West corner longitude (deg) = region_size * lon_nw_corner_enc - + /// 180 + #[cfg_attr(feature = "serde", serde(rename(serialize = "lon_nw_corner_enc")))] + pub lon_nw_corner_enc: u16, + /// Number of messages in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] + pub num_msgs: u8, + /// Position of this message in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] + pub seq_num: u8, + } + + impl WireFormat for GridDefinitionHeaderDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.region_size_inverse) + + WireFormat::len(&self.area_width) + + WireFormat::len(&self.lat_nw_corner_enc) + + WireFormat::len(&self.lon_nw_corner_enc) + + WireFormat::len(&self.num_msgs) + + WireFormat::len(&self.seq_num) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.region_size_inverse, buf); + WireFormat::write(&self.area_width, buf); + WireFormat::write(&self.lat_nw_corner_enc, buf); + WireFormat::write(&self.lon_nw_corner_enc, buf); + WireFormat::write(&self.num_msgs, buf); + WireFormat::write(&self.seq_num, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GridDefinitionHeaderDepA { + region_size_inverse: WireFormat::parse_unchecked(buf), + area_width: WireFormat::parse_unchecked(buf), + lat_nw_corner_enc: WireFormat::parse_unchecked(buf), + lon_nw_corner_enc: WireFormat::parse_unchecked(buf), + num_msgs: WireFormat::parse_unchecked(buf), + seq_num: WireFormat::parse_unchecked(buf), + } } } } -/// Header for the MSG_SSR_GRIDDED_CORRECTION message -/// -/// The LPP message contains nested variable length arrays which are not -/// supported in SBP, so each grid point will be identified by the index. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GriddedCorrectionHeader { - /// Unique identifier of the tile set this tile belongs to. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] - pub tile_set_id: u16, - /// Unique identifier of this tile in the tile set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] - pub tile_id: u16, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// Number of messages in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] - pub num_msgs: u16, - /// Position of this message in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] - pub seq_num: u16, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR atmospheric correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] - pub iod_atmo: u8, - /// Quality of the troposphere data. Encoded following RTCM DF389 - /// specification in units of m. - #[cfg_attr( - feature = "serde", - serde(rename(serialize = "tropo_quality_indicator")) - )] - pub tropo_quality_indicator: u8, -} +pub mod gridded_correction_header { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl WireFormat for GriddedCorrectionHeader { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tile_set_id) - + WireFormat::len(&self.tile_id) - + WireFormat::len(&self.time) - + WireFormat::len(&self.num_msgs) - + WireFormat::len(&self.seq_num) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_atmo) - + WireFormat::len(&self.tropo_quality_indicator) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tile_set_id, buf); - WireFormat::write(&self.tile_id, buf); - WireFormat::write(&self.time, buf); - WireFormat::write(&self.num_msgs, buf); - WireFormat::write(&self.seq_num, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_atmo, buf); - WireFormat::write(&self.tropo_quality_indicator, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - GriddedCorrectionHeader { - tile_set_id: WireFormat::parse_unchecked(buf), - tile_id: WireFormat::parse_unchecked(buf), - time: WireFormat::parse_unchecked(buf), - num_msgs: WireFormat::parse_unchecked(buf), - seq_num: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_atmo: WireFormat::parse_unchecked(buf), - tropo_quality_indicator: WireFormat::parse_unchecked(buf), + /// Header for the MSG_SSR_GRIDDED_CORRECTION message + /// + /// The LPP message contains nested variable length arrays which are not + /// supported in SBP, so each grid point will be identified by the index. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GriddedCorrectionHeader { + /// Unique identifier of the tile set this tile belongs to. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] + pub tile_set_id: u16, + /// Unique identifier of this tile in the tile set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] + pub tile_id: u16, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// Number of messages in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] + pub num_msgs: u16, + /// Position of this message in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] + pub seq_num: u16, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR atmospheric correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] + pub iod_atmo: u8, + /// Quality of the troposphere data. Encoded following RTCM DF389 + /// specification in units of m. + #[cfg_attr( + feature = "serde", + serde(rename(serialize = "tropo_quality_indicator")) + )] + pub tropo_quality_indicator: u8, + } + + impl WireFormat for GriddedCorrectionHeader { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tile_set_id) + + WireFormat::len(&self.tile_id) + + WireFormat::len(&self.time) + + WireFormat::len(&self.num_msgs) + + WireFormat::len(&self.seq_num) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_atmo) + + WireFormat::len(&self.tropo_quality_indicator) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tile_set_id, buf); + WireFormat::write(&self.tile_id, buf); + WireFormat::write(&self.time, buf); + WireFormat::write(&self.num_msgs, buf); + WireFormat::write(&self.seq_num, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_atmo, buf); + WireFormat::write(&self.tropo_quality_indicator, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GriddedCorrectionHeader { + tile_set_id: WireFormat::parse_unchecked(buf), + tile_id: WireFormat::parse_unchecked(buf), + time: WireFormat::parse_unchecked(buf), + num_msgs: WireFormat::parse_unchecked(buf), + seq_num: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_atmo: WireFormat::parse_unchecked(buf), + tropo_quality_indicator: WireFormat::parse_unchecked(buf), + } } } } -/// Header for MSG_SSR_GRIDDED_CORRECTION_DEP -/// -/// The 3GPP message contains nested variable length arrays which are not -/// supported in SBP, so each grid point will be identified by the index. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct GriddedCorrectionHeaderDepA { - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// Number of messages in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] - pub num_msgs: u16, - /// Position of this message in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] - pub seq_num: u16, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR atmospheric correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] - pub iod_atmo: u8, - /// Quality of the troposphere data. Encoded following RTCM DF389 - /// specification in units of m. - #[cfg_attr( - feature = "serde", - serde(rename(serialize = "tropo_quality_indicator")) - )] - pub tropo_quality_indicator: u8, -} +pub mod gridded_correction_header_dep_a { + #![allow(unused_imports)] -impl WireFormat for GriddedCorrectionHeaderDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.num_msgs) - + WireFormat::len(&self.seq_num) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_atmo) - + WireFormat::len(&self.tropo_quality_indicator) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.num_msgs, buf); - WireFormat::write(&self.seq_num, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_atmo, buf); - WireFormat::write(&self.tropo_quality_indicator, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - GriddedCorrectionHeaderDepA { - time: WireFormat::parse_unchecked(buf), - num_msgs: WireFormat::parse_unchecked(buf), - seq_num: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_atmo: WireFormat::parse_unchecked(buf), - tropo_quality_indicator: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Header for MSG_SSR_GRIDDED_CORRECTION_DEP + /// + /// The 3GPP message contains nested variable length arrays which are not + /// supported in SBP, so each grid point will be identified by the index. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct GriddedCorrectionHeaderDepA { + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// Number of messages in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] + pub num_msgs: u16, + /// Position of this message in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] + pub seq_num: u16, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR atmospheric correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] + pub iod_atmo: u8, + /// Quality of the troposphere data. Encoded following RTCM DF389 + /// specification in units of m. + #[cfg_attr( + feature = "serde", + serde(rename(serialize = "tropo_quality_indicator")) + )] + pub tropo_quality_indicator: u8, + } + + impl WireFormat for GriddedCorrectionHeaderDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.num_msgs) + + WireFormat::len(&self.seq_num) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_atmo) + + WireFormat::len(&self.tropo_quality_indicator) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.num_msgs, buf); + WireFormat::write(&self.seq_num, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_atmo, buf); + WireFormat::write(&self.tropo_quality_indicator, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + GriddedCorrectionHeaderDepA { + time: WireFormat::parse_unchecked(buf), + num_msgs: WireFormat::parse_unchecked(buf), + seq_num: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_atmo: WireFormat::parse_unchecked(buf), + tropo_quality_indicator: WireFormat::parse_unchecked(buf), + } } } } -/// Precise code biases correction -/// -/// The precise code biases message is to be added to the pseudorange of the -/// corresponding signal to get corrected pseudorange. It is an equivalent to -/// the 1059 / 1065 RTCM message types. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrCodeBiases { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR correction. A change of Issue Of Data SSR is used to - /// indicate a change in the SSR generating configuration - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] - pub iod_ssr: u8, - /// Code biases for the different satellite signals - #[cfg_attr(feature = "serde", serde(rename(serialize = "biases")))] - pub biases: Vec, -} +pub mod msg_ssr_code_biases { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrCodeBiases { - const MESSAGE_TYPE: u16 = 1505; - const MESSAGE_NAME: &'static str = "MSG_SSR_CODE_BIASES"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrCodeBiases { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Precise code biases correction + /// + /// The precise code biases message is to be added to the pseudorange of the + /// corresponding signal to get corrected pseudorange. It is an equivalent to + /// the 1059 / 1065 RTCM message types. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrCodeBiases { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR correction. A change of Issue Of Data SSR is used to + /// indicate a change in the SSR generating configuration + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] + pub iod_ssr: u8, + /// Code biases for the different satellite signals + #[cfg_attr(feature = "serde", serde(rename(serialize = "biases")))] + pub biases: Vec, + } + + impl ConcreteMessage for MsgSsrCodeBiases { + const MESSAGE_TYPE: u16 = 1505; + const MESSAGE_NAME: &'static str = "MSG_SSR_CODE_BIASES"; + } + + impl SbpMessage for MsgSsrCodeBiases { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrCodeBiases { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrCodeBiases(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrCodeBiases { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrCodeBiases(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrCodeBiases { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_ssr) - + WireFormat::len(&self.biases) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_ssr, buf); - WireFormat::write(&self.biases, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrCodeBiases { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_ssr: WireFormat::parse_unchecked(buf), - biases: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrCodeBiases { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_ssr) + + WireFormat::len(&self.biases) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_ssr, buf); + WireFormat::write(&self.biases, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrCodeBiases { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_ssr: WireFormat::parse_unchecked(buf), + biases: WireFormat::parse_unchecked(buf), + } } } } -/// Gridded troposphere and STEC correction residuals -/// -/// STEC residuals are per space vehicle, troposphere is not. -/// -/// It is typically equivalent to the QZSS CLAS Sub Type 9 messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrGriddedCorrection { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a gridded correction message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: GriddedCorrectionHeader, - /// Index of the grid point. - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u16, - /// Wet and hydrostatic vertical delays (mean, stddev). - #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] - pub tropo_delay_correction: TroposphericDelayCorrection, - /// STEC residuals for each satellite (mean, stddev). - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] - pub stec_residuals: Vec, -} +pub mod msg_ssr_gridded_correction { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrGriddedCorrection { - const MESSAGE_TYPE: u16 = 1532; - const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrGriddedCorrection { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Gridded troposphere and STEC correction residuals + /// + /// STEC residuals are per space vehicle, troposphere is not. + /// + /// It is typically equivalent to the QZSS CLAS Sub Type 9 messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrGriddedCorrection { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a gridded correction message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: GriddedCorrectionHeader, + /// Index of the grid point. + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u16, + /// Wet and hydrostatic vertical delays (mean, stddev). + #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] + pub tropo_delay_correction: TroposphericDelayCorrection, + /// STEC residuals for each satellite (mean, stddev). + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] + pub stec_residuals: Vec, + } + + impl ConcreteMessage for MsgSsrGriddedCorrection { + const MESSAGE_TYPE: u16 = 1532; + const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION"; + } + + impl SbpMessage for MsgSsrGriddedCorrection { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrGriddedCorrection { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrGriddedCorrection(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrGriddedCorrection { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrGriddedCorrection(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrGriddedCorrection { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) - + WireFormat::len(&self.index) - + WireFormat::len(&self.tropo_delay_correction) - + WireFormat::len(&self.stec_residuals) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.index, buf); - WireFormat::write(&self.tropo_delay_correction, buf); - WireFormat::write(&self.stec_residuals, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrGriddedCorrection { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - index: WireFormat::parse_unchecked(buf), - tropo_delay_correction: WireFormat::parse_unchecked(buf), - stec_residuals: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrGriddedCorrection { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + + WireFormat::len(&self.index) + + WireFormat::len(&self.tropo_delay_correction) + + WireFormat::len(&self.stec_residuals) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.index, buf); + WireFormat::write(&self.tropo_delay_correction, buf); + WireFormat::write(&self.stec_residuals, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrGriddedCorrection { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + index: WireFormat::parse_unchecked(buf), + tropo_delay_correction: WireFormat::parse_unchecked(buf), + stec_residuals: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrGriddedCorrectionDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a Gridded Correction message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: GriddedCorrectionHeaderDepA, - /// Index of the grid point - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u16, - /// Wet and hydrostatic vertical delays (mean, stddev) - #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] - pub tropo_delay_correction: TroposphericDelayCorrection, - /// STEC residuals for each satellite (mean, stddev) - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] - pub stec_residuals: Vec, -} - -impl ConcreteMessage for MsgSsrGriddedCorrectionDepA { - const MESSAGE_TYPE: u16 = 1530; - const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION_DEP_A"; -} - -impl SbpMessage for MsgSsrGriddedCorrectionDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id +pub mod msg_ssr_gridded_correction_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Deprecated + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrGriddedCorrectionDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a Gridded Correction message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: GriddedCorrectionHeaderDepA, + /// Index of the grid point + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u16, + /// Wet and hydrostatic vertical delays (mean, stddev) + #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] + pub tropo_delay_correction: TroposphericDelayCorrection, + /// STEC residuals for each satellite (mean, stddev) + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] + pub stec_residuals: Vec, + } + + impl ConcreteMessage for MsgSsrGriddedCorrectionDepA { + const MESSAGE_TYPE: u16 = 1530; + const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION_DEP_A"; + } + + impl SbpMessage for MsgSsrGriddedCorrectionDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgSsrGriddedCorrectionDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrGriddedCorrectionDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for MsgSsrGriddedCorrectionDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + + WireFormat::len(&self.index) + + WireFormat::len(&self.tropo_delay_correction) + + WireFormat::len(&self.stec_residuals) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.index, buf); + WireFormat::write(&self.tropo_delay_correction, buf); + WireFormat::write(&self.stec_residuals, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrGriddedCorrectionDepA { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + index: WireFormat::parse_unchecked(buf), + tropo_delay_correction: WireFormat::parse_unchecked(buf), + stec_residuals: WireFormat::parse_unchecked(buf), + } + } } } -impl TryFrom for MsgSsrGriddedCorrectionDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrGriddedCorrectionDepA(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_ssr_gridded_correction_no_std_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Deprecated + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrGriddedCorrectionNoStdDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a Gridded Correction message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: GriddedCorrectionHeaderDepA, + /// Index of the grid point + #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] + pub index: u16, + /// Wet and hydrostatic vertical delays + #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] + pub tropo_delay_correction: TroposphericDelayCorrectionNoStd, + /// STEC residuals for each satellite + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] + pub stec_residuals: Vec, + } + + impl ConcreteMessage for MsgSsrGriddedCorrectionNoStdDepA { + const MESSAGE_TYPE: u16 = 1520; + const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION_NO_STD_DEP_A"; + } + + impl SbpMessage for MsgSsrGriddedCorrectionNoStdDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSsrGriddedCorrectionDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) - + WireFormat::len(&self.index) - + WireFormat::len(&self.tropo_delay_correction) - + WireFormat::len(&self.stec_residuals) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.index, buf); - WireFormat::write(&self.tropo_delay_correction, buf); - WireFormat::write(&self.stec_residuals, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrGriddedCorrectionDepA { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - index: WireFormat::parse_unchecked(buf), - tropo_delay_correction: WireFormat::parse_unchecked(buf), - stec_residuals: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgSsrGriddedCorrectionNoStdDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrGriddedCorrectionNoStdDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Deprecated -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrGriddedCorrectionNoStdDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a Gridded Correction message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: GriddedCorrectionHeaderDepA, - /// Index of the grid point - #[cfg_attr(feature = "serde", serde(rename(serialize = "index")))] - pub index: u16, - /// Wet and hydrostatic vertical delays - #[cfg_attr(feature = "serde", serde(rename(serialize = "tropo_delay_correction")))] - pub tropo_delay_correction: TroposphericDelayCorrectionNoStd, - /// STEC residuals for each satellite - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_residuals")))] - pub stec_residuals: Vec, + impl WireFormat for MsgSsrGriddedCorrectionNoStdDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + + WireFormat::len(&self.index) + + WireFormat::len(&self.tropo_delay_correction) + + WireFormat::len(&self.stec_residuals) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.index, buf); + WireFormat::write(&self.tropo_delay_correction, buf); + WireFormat::write(&self.stec_residuals, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrGriddedCorrectionNoStdDepA { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + index: WireFormat::parse_unchecked(buf), + tropo_delay_correction: WireFormat::parse_unchecked(buf), + stec_residuals: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgSsrGriddedCorrectionNoStdDepA { - const MESSAGE_TYPE: u16 = 1520; - const MESSAGE_NAME: &'static str = "MSG_SSR_GRIDDED_CORRECTION_NO_STD_DEP_A"; -} +pub mod msg_ssr_grid_definition_dep_a { + #![allow(unused_imports)] -impl SbpMessage for MsgSsrGriddedCorrectionNoStdDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Deprecated + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrGridDefinitionDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a Gridded Correction message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: GridDefinitionHeaderDepA, + /// Run Length Encode list of quadrants that contain valid data. The spec + /// describes the encoding scheme in detail, but essentially the index of + /// the quadrants that contain transitions between valid and invalid (and + /// vice versa) are encoded as u8 integers. + #[cfg_attr(feature = "serde", serde(rename(serialize = "rle_list")))] + pub rle_list: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgSsrGridDefinitionDepA { + const MESSAGE_TYPE: u16 = 1525; + const MESSAGE_NAME: &'static str = "MSG_SSR_GRID_DEFINITION_DEP_A"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgSsrGridDefinitionDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrGriddedCorrectionNoStdDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrGriddedCorrectionNoStdDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrGridDefinitionDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrGridDefinitionDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrGriddedCorrectionNoStdDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) - + WireFormat::len(&self.index) - + WireFormat::len(&self.tropo_delay_correction) - + WireFormat::len(&self.stec_residuals) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.index, buf); - WireFormat::write(&self.tropo_delay_correction, buf); - WireFormat::write(&self.stec_residuals, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrGriddedCorrectionNoStdDepA { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - index: WireFormat::parse_unchecked(buf), - tropo_delay_correction: WireFormat::parse_unchecked(buf), - stec_residuals: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrGridDefinitionDepA { + const MIN_LEN: usize = + ::MIN_LEN + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.rle_list) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.rle_list, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrGridDefinitionDepA { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + rle_list: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrGridDefinitionDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a Gridded Correction message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: GridDefinitionHeaderDepA, - /// Run Length Encode list of quadrants that contain valid data. The spec - /// describes the encoding scheme in detail, but essentially the index of - /// the quadrants that contain transitions between valid and invalid (and - /// vice versa) are encoded as u8 integers. - #[cfg_attr(feature = "serde", serde(rename(serialize = "rle_list")))] - pub rle_list: Vec, -} +pub mod msg_ssr_orbit_clock { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrGridDefinitionDepA { - const MESSAGE_TYPE: u16 = 1525; - const MESSAGE_NAME: &'static str = "MSG_SSR_GRID_DEFINITION_DEP_A"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrGridDefinitionDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Precise orbit and clock correction + /// + /// The precise orbit and clock correction message is to be applied as a delta + /// correction to broadcast ephemeris and is an equivalent to the 1060 /1066 + /// RTCM message types. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrOrbitClock { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR correction. A change of Issue Of Data SSR is used to + /// indicate a change in the SSR generating configuration + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] + pub iod_ssr: u8, + /// Issue of broadcast ephemeris data or IODCRC (Beidou) + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] + pub iod: u32, + /// Orbit radial delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "radial")))] + pub radial: i32, + /// Orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "along")))] + pub along: i32, + /// Orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "cross")))] + pub cross: i32, + /// Velocity of orbit radial delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_radial")))] + pub dot_radial: i32, + /// Velocity of orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_along")))] + pub dot_along: i32, + /// Velocity of orbit cross delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_cross")))] + pub dot_cross: i32, + /// C0 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c0")))] + pub c0: i32, + /// C1 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c1")))] + pub c1: i32, + /// C2 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c2")))] + pub c2: i32, + } + + impl ConcreteMessage for MsgSsrOrbitClock { + const MESSAGE_TYPE: u16 = 1501; + const MESSAGE_NAME: &'static str = "MSG_SSR_ORBIT_CLOCK"; + } + + impl SbpMessage for MsgSsrOrbitClock { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrGridDefinitionDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrGridDefinitionDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrOrbitClock { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrOrbitClock(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrGridDefinitionDepA { - const MIN_LEN: usize = - ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.rle_list) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.rle_list, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrGridDefinitionDepA { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - rle_list: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrOrbitClock { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_ssr) + + WireFormat::len(&self.iod) + + WireFormat::len(&self.radial) + + WireFormat::len(&self.along) + + WireFormat::len(&self.cross) + + WireFormat::len(&self.dot_radial) + + WireFormat::len(&self.dot_along) + + WireFormat::len(&self.dot_cross) + + WireFormat::len(&self.c0) + + WireFormat::len(&self.c1) + + WireFormat::len(&self.c2) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_ssr, buf); + WireFormat::write(&self.iod, buf); + WireFormat::write(&self.radial, buf); + WireFormat::write(&self.along, buf); + WireFormat::write(&self.cross, buf); + WireFormat::write(&self.dot_radial, buf); + WireFormat::write(&self.dot_along, buf); + WireFormat::write(&self.dot_cross, buf); + WireFormat::write(&self.c0, buf); + WireFormat::write(&self.c1, buf); + WireFormat::write(&self.c2, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrOrbitClock { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_ssr: WireFormat::parse_unchecked(buf), + iod: WireFormat::parse_unchecked(buf), + radial: WireFormat::parse_unchecked(buf), + along: WireFormat::parse_unchecked(buf), + cross: WireFormat::parse_unchecked(buf), + dot_radial: WireFormat::parse_unchecked(buf), + dot_along: WireFormat::parse_unchecked(buf), + dot_cross: WireFormat::parse_unchecked(buf), + c0: WireFormat::parse_unchecked(buf), + c1: WireFormat::parse_unchecked(buf), + c2: WireFormat::parse_unchecked(buf), + } } } } -/// Precise orbit and clock correction -/// -/// The precise orbit and clock correction message is to be applied as a delta -/// correction to broadcast ephemeris and is an equivalent to the 1060 /1066 -/// RTCM message types. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrOrbitClock { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR correction. A change of Issue Of Data SSR is used to - /// indicate a change in the SSR generating configuration - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] - pub iod_ssr: u8, - /// Issue of broadcast ephemeris data or IODCRC (Beidou) - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] - pub iod: u32, - /// Orbit radial delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "radial")))] - pub radial: i32, - /// Orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "along")))] - pub along: i32, - /// Orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "cross")))] - pub cross: i32, - /// Velocity of orbit radial delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_radial")))] - pub dot_radial: i32, - /// Velocity of orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_along")))] - pub dot_along: i32, - /// Velocity of orbit cross delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_cross")))] - pub dot_cross: i32, - /// C0 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c0")))] - pub c0: i32, - /// C1 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c1")))] - pub c1: i32, - /// C2 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c2")))] - pub c2: i32, -} - -impl ConcreteMessage for MsgSsrOrbitClock { - const MESSAGE_TYPE: u16 = 1501; - const MESSAGE_NAME: &'static str = "MSG_SSR_ORBIT_CLOCK"; -} - -impl SbpMessage for MsgSsrOrbitClock { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN +pub mod msg_ssr_orbit_clock_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Deprecated + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrOrbitClockDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR correction. A change of Issue Of Data SSR is used to + /// indicate a change in the SSR generating configuration + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] + pub iod_ssr: u8, + /// Issue of broadcast ephemeris data + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] + pub iod: u8, + /// Orbit radial delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "radial")))] + pub radial: i32, + /// Orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "along")))] + pub along: i32, + /// Orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "cross")))] + pub cross: i32, + /// Velocity of orbit radial delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_radial")))] + pub dot_radial: i32, + /// Velocity of orbit along delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_along")))] + pub dot_along: i32, + /// Velocity of orbit cross delta correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_cross")))] + pub dot_cross: i32, + /// C0 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c0")))] + pub c0: i32, + /// C1 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c1")))] + pub c1: i32, + /// C2 polynomial coefficient for correction of broadcast satellite clock + #[cfg_attr(feature = "serde", serde(rename(serialize = "c2")))] + pub c2: i32, + } + + impl ConcreteMessage for MsgSsrOrbitClockDepA { + const MESSAGE_TYPE: u16 = 1500; + const MESSAGE_NAME: &'static str = "MSG_SSR_ORBIT_CLOCK_DEP_A"; + } + + impl SbpMessage for MsgSsrOrbitClockDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrOrbitClock { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrOrbitClock(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrOrbitClockDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrOrbitClockDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrOrbitClock { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_ssr) - + WireFormat::len(&self.iod) - + WireFormat::len(&self.radial) - + WireFormat::len(&self.along) - + WireFormat::len(&self.cross) - + WireFormat::len(&self.dot_radial) - + WireFormat::len(&self.dot_along) - + WireFormat::len(&self.dot_cross) - + WireFormat::len(&self.c0) - + WireFormat::len(&self.c1) - + WireFormat::len(&self.c2) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_ssr, buf); - WireFormat::write(&self.iod, buf); - WireFormat::write(&self.radial, buf); - WireFormat::write(&self.along, buf); - WireFormat::write(&self.cross, buf); - WireFormat::write(&self.dot_radial, buf); - WireFormat::write(&self.dot_along, buf); - WireFormat::write(&self.dot_cross, buf); - WireFormat::write(&self.c0, buf); - WireFormat::write(&self.c1, buf); - WireFormat::write(&self.c2, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrOrbitClock { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_ssr: WireFormat::parse_unchecked(buf), - iod: WireFormat::parse_unchecked(buf), - radial: WireFormat::parse_unchecked(buf), - along: WireFormat::parse_unchecked(buf), - cross: WireFormat::parse_unchecked(buf), - dot_radial: WireFormat::parse_unchecked(buf), - dot_along: WireFormat::parse_unchecked(buf), - dot_cross: WireFormat::parse_unchecked(buf), - c0: WireFormat::parse_unchecked(buf), - c1: WireFormat::parse_unchecked(buf), - c2: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrOrbitClockDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_ssr) + + WireFormat::len(&self.iod) + + WireFormat::len(&self.radial) + + WireFormat::len(&self.along) + + WireFormat::len(&self.cross) + + WireFormat::len(&self.dot_radial) + + WireFormat::len(&self.dot_along) + + WireFormat::len(&self.dot_cross) + + WireFormat::len(&self.c0) + + WireFormat::len(&self.c1) + + WireFormat::len(&self.c2) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_ssr, buf); + WireFormat::write(&self.iod, buf); + WireFormat::write(&self.radial, buf); + WireFormat::write(&self.along, buf); + WireFormat::write(&self.cross, buf); + WireFormat::write(&self.dot_radial, buf); + WireFormat::write(&self.dot_along, buf); + WireFormat::write(&self.dot_cross, buf); + WireFormat::write(&self.c0, buf); + WireFormat::write(&self.c1, buf); + WireFormat::write(&self.c2, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrOrbitClockDepA { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_ssr: WireFormat::parse_unchecked(buf), + iod: WireFormat::parse_unchecked(buf), + radial: WireFormat::parse_unchecked(buf), + along: WireFormat::parse_unchecked(buf), + cross: WireFormat::parse_unchecked(buf), + dot_radial: WireFormat::parse_unchecked(buf), + dot_along: WireFormat::parse_unchecked(buf), + dot_cross: WireFormat::parse_unchecked(buf), + c0: WireFormat::parse_unchecked(buf), + c1: WireFormat::parse_unchecked(buf), + c2: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrOrbitClockDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR correction. A change of Issue Of Data SSR is used to - /// indicate a change in the SSR generating configuration - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] - pub iod_ssr: u8, - /// Issue of broadcast ephemeris data - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod")))] - pub iod: u8, - /// Orbit radial delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "radial")))] - pub radial: i32, - /// Orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "along")))] - pub along: i32, - /// Orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "cross")))] - pub cross: i32, - /// Velocity of orbit radial delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_radial")))] - pub dot_radial: i32, - /// Velocity of orbit along delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_along")))] - pub dot_along: i32, - /// Velocity of orbit cross delta correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "dot_cross")))] - pub dot_cross: i32, - /// C0 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c0")))] - pub c0: i32, - /// C1 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c1")))] - pub c1: i32, - /// C2 polynomial coefficient for correction of broadcast satellite clock - #[cfg_attr(feature = "serde", serde(rename(serialize = "c2")))] - pub c2: i32, -} +pub mod msg_ssr_phase_biases { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrOrbitClockDepA { - const MESSAGE_TYPE: u16 = 1500; - const MESSAGE_NAME: &'static str = "MSG_SSR_ORBIT_CLOCK_DEP_A"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrOrbitClockDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// Precise phase biases correction + /// + /// The precise phase biases message contains the biases to be added to the + /// carrier phase of the corresponding signal to get corrected carrier phase + /// measurement, as well as the satellite yaw angle to be applied to compute + /// the phase wind-up correction. It is typically an equivalent to the 1265 + /// RTCM message types. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrPhaseBiases { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR correction. A change of Issue Of Data SSR is used to + /// indicate a change in the SSR generating configuration + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] + pub iod_ssr: u8, + /// Indicator for the dispersive phase biases property. + #[cfg_attr(feature = "serde", serde(rename(serialize = "dispersive_bias")))] + pub dispersive_bias: u8, + /// Consistency indicator for Melbourne-Wubbena linear combinations + #[cfg_attr(feature = "serde", serde(rename(serialize = "mw_consistency")))] + pub mw_consistency: u8, + /// Satellite yaw angle + #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw")))] + pub yaw: u16, + /// Satellite yaw angle rate + #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw_rate")))] + pub yaw_rate: i8, + /// Phase biases corrections for a satellite being tracked. + #[cfg_attr(feature = "serde", serde(rename(serialize = "biases")))] + pub biases: Vec, + } + + impl ConcreteMessage for MsgSsrPhaseBiases { + const MESSAGE_TYPE: u16 = 1510; + const MESSAGE_NAME: &'static str = "MSG_SSR_PHASE_BIASES"; + } + + impl SbpMessage for MsgSsrPhaseBiases { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrOrbitClockDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrOrbitClockDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrPhaseBiases { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrPhaseBiases(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrOrbitClockDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_ssr) - + WireFormat::len(&self.iod) - + WireFormat::len(&self.radial) - + WireFormat::len(&self.along) - + WireFormat::len(&self.cross) - + WireFormat::len(&self.dot_radial) - + WireFormat::len(&self.dot_along) - + WireFormat::len(&self.dot_cross) - + WireFormat::len(&self.c0) - + WireFormat::len(&self.c1) - + WireFormat::len(&self.c2) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_ssr, buf); - WireFormat::write(&self.iod, buf); - WireFormat::write(&self.radial, buf); - WireFormat::write(&self.along, buf); - WireFormat::write(&self.cross, buf); - WireFormat::write(&self.dot_radial, buf); - WireFormat::write(&self.dot_along, buf); - WireFormat::write(&self.dot_cross, buf); - WireFormat::write(&self.c0, buf); - WireFormat::write(&self.c1, buf); - WireFormat::write(&self.c2, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrOrbitClockDepA { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_ssr: WireFormat::parse_unchecked(buf), - iod: WireFormat::parse_unchecked(buf), - radial: WireFormat::parse_unchecked(buf), - along: WireFormat::parse_unchecked(buf), - cross: WireFormat::parse_unchecked(buf), - dot_radial: WireFormat::parse_unchecked(buf), - dot_along: WireFormat::parse_unchecked(buf), - dot_cross: WireFormat::parse_unchecked(buf), - c0: WireFormat::parse_unchecked(buf), - c1: WireFormat::parse_unchecked(buf), - c2: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrPhaseBiases { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_ssr) + + WireFormat::len(&self.dispersive_bias) + + WireFormat::len(&self.mw_consistency) + + WireFormat::len(&self.yaw) + + WireFormat::len(&self.yaw_rate) + + WireFormat::len(&self.biases) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_ssr, buf); + WireFormat::write(&self.dispersive_bias, buf); + WireFormat::write(&self.mw_consistency, buf); + WireFormat::write(&self.yaw, buf); + WireFormat::write(&self.yaw_rate, buf); + WireFormat::write(&self.biases, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrPhaseBiases { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_ssr: WireFormat::parse_unchecked(buf), + dispersive_bias: WireFormat::parse_unchecked(buf), + mw_consistency: WireFormat::parse_unchecked(buf), + yaw: WireFormat::parse_unchecked(buf), + yaw_rate: WireFormat::parse_unchecked(buf), + biases: WireFormat::parse_unchecked(buf), + } } } } -/// Precise phase biases correction -/// -/// The precise phase biases message contains the biases to be added to the -/// carrier phase of the corresponding signal to get corrected carrier phase -/// measurement, as well as the satellite yaw angle to be applied to compute -/// the phase wind-up correction. It is typically an equivalent to the 1265 -/// RTCM message types. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrPhaseBiases { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR correction. A change of Issue Of Data SSR is used to - /// indicate a change in the SSR generating configuration - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_ssr")))] - pub iod_ssr: u8, - /// Indicator for the dispersive phase biases property. - #[cfg_attr(feature = "serde", serde(rename(serialize = "dispersive_bias")))] - pub dispersive_bias: u8, - /// Consistency indicator for Melbourne-Wubbena linear combinations - #[cfg_attr(feature = "serde", serde(rename(serialize = "mw_consistency")))] - pub mw_consistency: u8, - /// Satellite yaw angle - #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw")))] - pub yaw: u16, - /// Satellite yaw angle rate - #[cfg_attr(feature = "serde", serde(rename(serialize = "yaw_rate")))] - pub yaw_rate: i8, - /// Phase biases corrections for a satellite being tracked. - #[cfg_attr(feature = "serde", serde(rename(serialize = "biases")))] - pub biases: Vec, -} - -impl ConcreteMessage for MsgSsrPhaseBiases { - const MESSAGE_TYPE: u16 = 1510; - const MESSAGE_NAME: &'static str = "MSG_SSR_PHASE_BIASES"; -} +pub mod msg_ssr_satellite_apc { + #![allow(unused_imports)] -impl SbpMessage for MsgSsrPhaseBiases { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Satellite antenna phase center corrections + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrSatelliteApc { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Satellite antenna phase center corrections + #[cfg_attr(feature = "serde", serde(rename(serialize = "apc")))] + pub apc: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgSsrSatelliteApc { + const MESSAGE_TYPE: u16 = 1540; + const MESSAGE_NAME: &'static str = "MSG_SSR_SATELLITE_APC"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgSsrSatelliteApc { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrPhaseBiases { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrPhaseBiases(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrSatelliteApc { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrSatelliteApc(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrPhaseBiases { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_ssr) - + WireFormat::len(&self.dispersive_bias) - + WireFormat::len(&self.mw_consistency) - + WireFormat::len(&self.yaw) - + WireFormat::len(&self.yaw_rate) - + WireFormat::len(&self.biases) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_ssr, buf); - WireFormat::write(&self.dispersive_bias, buf); - WireFormat::write(&self.mw_consistency, buf); - WireFormat::write(&self.yaw, buf); - WireFormat::write(&self.yaw_rate, buf); - WireFormat::write(&self.biases, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrPhaseBiases { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_ssr: WireFormat::parse_unchecked(buf), - dispersive_bias: WireFormat::parse_unchecked(buf), - mw_consistency: WireFormat::parse_unchecked(buf), - yaw: WireFormat::parse_unchecked(buf), - yaw_rate: WireFormat::parse_unchecked(buf), - biases: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrSatelliteApc { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.apc) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.apc, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrSatelliteApc { + sender_id: None, + apc: WireFormat::parse_unchecked(buf), + } } } } -/// Satellite antenna phase center corrections -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrSatelliteApc { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Satellite antenna phase center corrections - #[cfg_attr(feature = "serde", serde(rename(serialize = "apc")))] - pub apc: Vec, -} +pub mod msg_ssr_stec_correction { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrSatelliteApc { - const MESSAGE_TYPE: u16 = 1540; - const MESSAGE_NAME: &'static str = "MSG_SSR_SATELLITE_APC"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrSatelliteApc { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + /// STEC correction polynomial coefficients + /// + /// The Slant Total Electron Content per space vehicle, given as polynomial + /// approximation for a given tile. This should be combined with the + /// MSG_SSR_GRIDDED_CORRECTION message to get the state space representation + /// of the atmospheric delay. + /// + /// It is typically equivalent to the QZSS CLAS Sub Type 8 messages. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrStecCorrection { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a STEC polynomial coefficient message. + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: STECHeader, + /// Array of STEC polynomial coefficients for each space vehicle. + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_sat_list")))] + pub stec_sat_list: Vec, + } + + impl ConcreteMessage for MsgSsrStecCorrection { + const MESSAGE_TYPE: u16 = 1531; + const MESSAGE_NAME: &'static str = "MSG_SSR_STEC_CORRECTION"; + } + + impl SbpMessage for MsgSsrStecCorrection { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } -} -impl TryFrom for MsgSsrSatelliteApc { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrSatelliteApc(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for MsgSsrStecCorrection { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrStecCorrection(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -impl WireFormat for MsgSsrSatelliteApc { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.apc) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.apc, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrSatelliteApc { - sender_id: None, - apc: WireFormat::parse_unchecked(buf), + impl WireFormat for MsgSsrStecCorrection { + const MIN_LEN: usize = + ::MIN_LEN + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.stec_sat_list) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.stec_sat_list, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrStecCorrection { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + stec_sat_list: WireFormat::parse_unchecked(buf), + } } } } -/// STEC correction polynomial coefficients -/// -/// The Slant Total Electron Content per space vehicle, given as polynomial -/// approximation for a given tile. This should be combined with the -/// MSG_SSR_GRIDDED_CORRECTION message to get the state space representation -/// of the atmospheric delay. -/// -/// It is typically equivalent to the QZSS CLAS Sub Type 8 messages. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrStecCorrection { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a STEC polynomial coefficient message. - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: STECHeader, - /// Array of STEC polynomial coefficients for each space vehicle. - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_sat_list")))] - pub stec_sat_list: Vec, -} - -impl ConcreteMessage for MsgSsrStecCorrection { - const MESSAGE_TYPE: u16 = 1531; - const MESSAGE_NAME: &'static str = "MSG_SSR_STEC_CORRECTION"; -} +pub mod msg_ssr_stec_correction_dep_a { + #![allow(unused_imports)] -impl SbpMessage for MsgSsrStecCorrection { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + /// Deprecated + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrStecCorrectionDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Header of a STEC message + #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] + pub header: STECHeaderDepA, + /// Array of STEC information for each space vehicle + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_sat_list")))] + pub stec_sat_list: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgSsrStecCorrectionDepA { + const MESSAGE_TYPE: u16 = 1515; + const MESSAGE_NAME: &'static str = "MSG_SSR_STEC_CORRECTION_DEP_A"; } -} -impl TryFrom for MsgSsrStecCorrection { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrStecCorrection(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgSsrStecCorrectionDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSsrStecCorrection { - const MIN_LEN: usize = - ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.stec_sat_list) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.stec_sat_list, buf); + impl TryFrom for MsgSsrStecCorrectionDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrStecCorrectionDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrStecCorrection { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - stec_sat_list: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSsrStecCorrectionDepA { + const MIN_LEN: usize = + ::MIN_LEN + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.header) + WireFormat::len(&self.stec_sat_list) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.header, buf); + WireFormat::write(&self.stec_sat_list, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrStecCorrectionDepA { + sender_id: None, + header: WireFormat::parse_unchecked(buf), + stec_sat_list: WireFormat::parse_unchecked(buf), + } } } } -/// Deprecated -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrStecCorrectionDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Header of a STEC message - #[cfg_attr(feature = "serde", serde(rename(serialize = "header")))] - pub header: STECHeaderDepA, - /// Array of STEC information for each space vehicle - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_sat_list")))] - pub stec_sat_list: Vec, -} +pub mod msg_ssr_tile_definition { + #![allow(unused_imports)] -impl ConcreteMessage for MsgSsrStecCorrectionDepA { - const MESSAGE_TYPE: u16 = 1515; - const MESSAGE_NAME: &'static str = "MSG_SSR_STEC_CORRECTION_DEP_A"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgSsrStecCorrectionDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + /// Definition of a SSR atmospheric correction tile. -impl TryFrom for MsgSsrStecCorrectionDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrStecCorrectionDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + /// + /// Provides the correction point coordinates for the atmospheric correction + /// values in the MSG_SSR_STEC_CORRECTION and MSG_SSR_GRIDDED_CORRECTION + /// messages. + /// + /// Based on ETSI TS 137 355 V16.1.0 (LTE Positioning Protocol) information + /// element GNSS-SSR-CorrectionPoints. SBP only supports gridded arrays of + /// correction points, not lists of points. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSsrTileDefinition { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Unique identifier of the tile set this tile belongs to. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] + pub tile_set_id: u16, + /// Unique identifier of this tile in the tile set. + /// See GNSS-SSR-ArrayOfCorrectionPoints field correctionPointSetID. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] + pub tile_id: u16, + /// North-West corner correction point latitude. + /// + /// The relation between the latitude X in the range \[-90, 90\] and the coded + /// number N is: + /// + /// N = floor((X / 90) * 2^14) + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field referencePointLatitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "corner_nw_lat")))] + pub corner_nw_lat: i16, + /// North-West corner correction point longitude. + /// + /// The relation between the longitude X in the range \[-180, 180\] and the + /// coded number N is: + /// + /// N = floor((X / 180) * 2^15) + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field referencePointLongitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "corner_nw_lon")))] + pub corner_nw_lon: i16, + /// Spacing of the correction points in the latitude direction. + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field stepOfLatitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "spacing_lat")))] + pub spacing_lat: u16, + /// Spacing of the correction points in the longitude direction. + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field stepOfLongitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "spacing_lon")))] + pub spacing_lon: u16, + /// Number of steps in the latitude direction. + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field numberOfStepsLatitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "rows")))] + pub rows: u16, + /// Number of steps in the longitude direction. + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field numberOfStepsLongitude. + #[cfg_attr(feature = "serde", serde(rename(serialize = "cols")))] + pub cols: u16, + /// Specifies the availability of correction data at the correction points + /// in the array. + /// + /// If a specific bit is enabled (set to 1), the correction is not + /// available. Only the first rows * cols bits are used, the remainder are + /// set to 0. If there are more then 64 correction points the remaining + /// corrections are always available. + /// + /// Starting with the northwest corner of the array (top left on a north + /// oriented map) the correction points are enumerated with row precedence - + /// first row west to east, second row west to east, until last row west to + /// east - ending with the southeast corner of the array. + /// + /// See GNSS-SSR-ArrayOfCorrectionPoints field bitmaskOfGrids but note the + /// definition of the bits is inverted. + #[cfg_attr(feature = "serde", serde(rename(serialize = "bitmask")))] + pub bitmask: u64, + } + + impl ConcreteMessage for MsgSsrTileDefinition { + const MESSAGE_TYPE: u16 = 1526; + const MESSAGE_NAME: &'static str = "MSG_SSR_TILE_DEFINITION"; + } + + impl SbpMessage for MsgSsrTileDefinition { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSsrStecCorrectionDepA { - const MIN_LEN: usize = - ::MIN_LEN + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.header) + WireFormat::len(&self.stec_sat_list) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.header, buf); - WireFormat::write(&self.stec_sat_list, buf); + impl TryFrom for MsgSsrTileDefinition { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSsrTileDefinition(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrStecCorrectionDepA { - sender_id: None, - header: WireFormat::parse_unchecked(buf), - stec_sat_list: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSsrTileDefinition { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tile_set_id) + + WireFormat::len(&self.tile_id) + + WireFormat::len(&self.corner_nw_lat) + + WireFormat::len(&self.corner_nw_lon) + + WireFormat::len(&self.spacing_lat) + + WireFormat::len(&self.spacing_lon) + + WireFormat::len(&self.rows) + + WireFormat::len(&self.cols) + + WireFormat::len(&self.bitmask) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tile_set_id, buf); + WireFormat::write(&self.tile_id, buf); + WireFormat::write(&self.corner_nw_lat, buf); + WireFormat::write(&self.corner_nw_lon, buf); + WireFormat::write(&self.spacing_lat, buf); + WireFormat::write(&self.spacing_lon, buf); + WireFormat::write(&self.rows, buf); + WireFormat::write(&self.cols, buf); + WireFormat::write(&self.bitmask, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSsrTileDefinition { + sender_id: None, + tile_set_id: WireFormat::parse_unchecked(buf), + tile_id: WireFormat::parse_unchecked(buf), + corner_nw_lat: WireFormat::parse_unchecked(buf), + corner_nw_lon: WireFormat::parse_unchecked(buf), + spacing_lat: WireFormat::parse_unchecked(buf), + spacing_lon: WireFormat::parse_unchecked(buf), + rows: WireFormat::parse_unchecked(buf), + cols: WireFormat::parse_unchecked(buf), + bitmask: WireFormat::parse_unchecked(buf), + } } } } -/// Definition of a SSR atmospheric correction tile. - -/// -/// Provides the correction point coordinates for the atmospheric correction -/// values in the MSG_SSR_STEC_CORRECTION and MSG_SSR_GRIDDED_CORRECTION -/// messages. -/// -/// Based on ETSI TS 137 355 V16.1.0 (LTE Positioning Protocol) information -/// element GNSS-SSR-CorrectionPoints. SBP only supports gridded arrays of -/// correction points, not lists of points. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSsrTileDefinition { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Unique identifier of the tile set this tile belongs to. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] - pub tile_set_id: u16, - /// Unique identifier of this tile in the tile set. - /// See GNSS-SSR-ArrayOfCorrectionPoints field correctionPointSetID. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] - pub tile_id: u16, - /// North-West corner correction point latitude. - /// - /// The relation between the latitude X in the range \[-90, 90\] and the coded - /// number N is: - /// - /// N = floor((X / 90) * 2^14) - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field referencePointLatitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "corner_nw_lat")))] - pub corner_nw_lat: i16, - /// North-West corner correction point longitude. - /// - /// The relation between the longitude X in the range \[-180, 180\] and the - /// coded number N is: - /// - /// N = floor((X / 180) * 2^15) - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field referencePointLongitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "corner_nw_lon")))] - pub corner_nw_lon: i16, - /// Spacing of the correction points in the latitude direction. - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field stepOfLatitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "spacing_lat")))] - pub spacing_lat: u16, - /// Spacing of the correction points in the longitude direction. - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field stepOfLongitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "spacing_lon")))] - pub spacing_lon: u16, - /// Number of steps in the latitude direction. - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field numberOfStepsLatitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "rows")))] - pub rows: u16, - /// Number of steps in the longitude direction. - /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field numberOfStepsLongitude. - #[cfg_attr(feature = "serde", serde(rename(serialize = "cols")))] - pub cols: u16, - /// Specifies the availability of correction data at the correction points - /// in the array. - /// - /// If a specific bit is enabled (set to 1), the correction is not - /// available. Only the first rows * cols bits are used, the remainder are - /// set to 0. If there are more then 64 correction points the remaining - /// corrections are always available. +pub mod phase_biases_content { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// SSR phase biases corrections for a particular satellite /// - /// Starting with the northwest corner of the array (top left on a north - /// oriented map) the correction points are enumerated with row precedence - - /// first row west to east, second row west to east, until last row west to - /// east - ending with the southeast corner of the array. + /// Phase biases are to be added to carrier phase measurements. /// - /// See GNSS-SSR-ArrayOfCorrectionPoints field bitmaskOfGrids but note the - /// definition of the bits is inverted. - #[cfg_attr(feature = "serde", serde(rename(serialize = "bitmask")))] - pub bitmask: u64, + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct PhaseBiasesContent { + /// Signal encoded following RTCM specifications (DF380, DF381, DF382 and + /// DF467) + #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] + pub code: u8, + /// Indicator for integer property + #[cfg_attr(feature = "serde", serde(rename(serialize = "integer_indicator")))] + pub integer_indicator: u8, + /// Indicator for two groups of Wide-Lane(s) integer property + #[cfg_attr( + feature = "serde", + serde(rename(serialize = "widelane_integer_indicator")) + )] + pub widelane_integer_indicator: u8, + /// Signal phase discontinuity counter. Increased for every discontinuity in + /// phase. + #[cfg_attr(feature = "serde", serde(rename(serialize = "discontinuity_counter")))] + pub discontinuity_counter: u8, + /// Phase bias for specified signal + #[cfg_attr(feature = "serde", serde(rename(serialize = "bias")))] + pub bias: i32, + } + + impl WireFormat for PhaseBiasesContent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.code) + + WireFormat::len(&self.integer_indicator) + + WireFormat::len(&self.widelane_integer_indicator) + + WireFormat::len(&self.discontinuity_counter) + + WireFormat::len(&self.bias) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.code, buf); + WireFormat::write(&self.integer_indicator, buf); + WireFormat::write(&self.widelane_integer_indicator, buf); + WireFormat::write(&self.discontinuity_counter, buf); + WireFormat::write(&self.bias, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + PhaseBiasesContent { + code: WireFormat::parse_unchecked(buf), + integer_indicator: WireFormat::parse_unchecked(buf), + widelane_integer_indicator: WireFormat::parse_unchecked(buf), + discontinuity_counter: WireFormat::parse_unchecked(buf), + bias: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgSsrTileDefinition { - const MESSAGE_TYPE: u16 = 1526; - const MESSAGE_NAME: &'static str = "MSG_SSR_TILE_DEFINITION"; -} +pub mod stec_header { + #![allow(unused_imports)] -impl SbpMessage for MsgSsrTileDefinition { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN - } -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl TryFrom for MsgSsrTileDefinition { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSsrTileDefinition(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Header for the MSG_SSR_STEC_CORRECTION message + /// + /// A full set of STEC information will likely span multiple SBP messages, + /// since SBP message a limited to 255 bytes. The header is used to tie + /// multiple SBP messages into a sequence. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct STECHeader { + /// Unique identifier of the tile set this tile belongs to. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] + pub tile_set_id: u16, + /// Unique identifier of this tile in the tile set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] + pub tile_id: u16, + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// Number of messages in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] + pub num_msgs: u8, + /// Position of this message in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] + pub seq_num: u8, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR atmospheric correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] + pub iod_atmo: u8, + } + + impl WireFormat for STECHeader { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tile_set_id) + + WireFormat::len(&self.tile_id) + + WireFormat::len(&self.time) + + WireFormat::len(&self.num_msgs) + + WireFormat::len(&self.seq_num) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_atmo) } - } -} - -impl WireFormat for MsgSsrTileDefinition { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tile_set_id) - + WireFormat::len(&self.tile_id) - + WireFormat::len(&self.corner_nw_lat) - + WireFormat::len(&self.corner_nw_lon) - + WireFormat::len(&self.spacing_lat) - + WireFormat::len(&self.spacing_lon) - + WireFormat::len(&self.rows) - + WireFormat::len(&self.cols) - + WireFormat::len(&self.bitmask) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tile_set_id, buf); - WireFormat::write(&self.tile_id, buf); - WireFormat::write(&self.corner_nw_lat, buf); - WireFormat::write(&self.corner_nw_lon, buf); - WireFormat::write(&self.spacing_lat, buf); - WireFormat::write(&self.spacing_lon, buf); - WireFormat::write(&self.rows, buf); - WireFormat::write(&self.cols, buf); - WireFormat::write(&self.bitmask, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSsrTileDefinition { - sender_id: None, - tile_set_id: WireFormat::parse_unchecked(buf), - tile_id: WireFormat::parse_unchecked(buf), - corner_nw_lat: WireFormat::parse_unchecked(buf), - corner_nw_lon: WireFormat::parse_unchecked(buf), - spacing_lat: WireFormat::parse_unchecked(buf), - spacing_lon: WireFormat::parse_unchecked(buf), - rows: WireFormat::parse_unchecked(buf), - cols: WireFormat::parse_unchecked(buf), - bitmask: WireFormat::parse_unchecked(buf), + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tile_set_id, buf); + WireFormat::write(&self.tile_id, buf); + WireFormat::write(&self.time, buf); + WireFormat::write(&self.num_msgs, buf); + WireFormat::write(&self.seq_num, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_atmo, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + STECHeader { + tile_set_id: WireFormat::parse_unchecked(buf), + tile_id: WireFormat::parse_unchecked(buf), + time: WireFormat::parse_unchecked(buf), + num_msgs: WireFormat::parse_unchecked(buf), + seq_num: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_atmo: WireFormat::parse_unchecked(buf), + } } } } -/// SSR phase biases corrections for a particular satellite -/// -/// Phase biases are to be added to carrier phase measurements. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct PhaseBiasesContent { - /// Signal encoded following RTCM specifications (DF380, DF381, DF382 and - /// DF467) - #[cfg_attr(feature = "serde", serde(rename(serialize = "code")))] - pub code: u8, - /// Indicator for integer property - #[cfg_attr(feature = "serde", serde(rename(serialize = "integer_indicator")))] - pub integer_indicator: u8, - /// Indicator for two groups of Wide-Lane(s) integer property - #[cfg_attr( - feature = "serde", - serde(rename(serialize = "widelane_integer_indicator")) - )] - pub widelane_integer_indicator: u8, - /// Signal phase discontinuity counter. Increased for every discontinuity in - /// phase. - #[cfg_attr(feature = "serde", serde(rename(serialize = "discontinuity_counter")))] - pub discontinuity_counter: u8, - /// Phase bias for specified signal - #[cfg_attr(feature = "serde", serde(rename(serialize = "bias")))] - pub bias: i32, -} +pub mod stec_header_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl WireFormat for PhaseBiasesContent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.code) - + WireFormat::len(&self.integer_indicator) - + WireFormat::len(&self.widelane_integer_indicator) - + WireFormat::len(&self.discontinuity_counter) - + WireFormat::len(&self.bias) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.code, buf); - WireFormat::write(&self.integer_indicator, buf); - WireFormat::write(&self.widelane_integer_indicator, buf); - WireFormat::write(&self.discontinuity_counter, buf); - WireFormat::write(&self.bias, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - PhaseBiasesContent { - code: WireFormat::parse_unchecked(buf), - integer_indicator: WireFormat::parse_unchecked(buf), - widelane_integer_indicator: WireFormat::parse_unchecked(buf), - discontinuity_counter: WireFormat::parse_unchecked(buf), - bias: WireFormat::parse_unchecked(buf), + /// Header for MSG_SSR_STEC_CORRECTION_DEP message + /// + /// A full set of STEC information will likely span multiple SBP messages, + /// since SBP message a limited to 255 bytes. The header is used to tie + /// multiple SBP messages into a sequence. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct STECHeaderDepA { + /// GNSS reference time of the correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: GpsTimeSec, + /// Number of messages in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] + pub num_msgs: u8, + /// Position of this message in the dataset + #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] + pub seq_num: u8, + /// Update interval between consecutive corrections. Encoded following RTCM + /// DF391 specification. + #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] + pub update_interval: u8, + /// IOD of the SSR atmospheric correction + #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] + pub iod_atmo: u8, + } + + impl WireFormat for STECHeaderDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.num_msgs) + + WireFormat::len(&self.seq_num) + + WireFormat::len(&self.update_interval) + + WireFormat::len(&self.iod_atmo) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.num_msgs, buf); + WireFormat::write(&self.seq_num, buf); + WireFormat::write(&self.update_interval, buf); + WireFormat::write(&self.iod_atmo, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + STECHeaderDepA { + time: WireFormat::parse_unchecked(buf), + num_msgs: WireFormat::parse_unchecked(buf), + seq_num: WireFormat::parse_unchecked(buf), + update_interval: WireFormat::parse_unchecked(buf), + iod_atmo: WireFormat::parse_unchecked(buf), + } } } } -/// Header for the MSG_SSR_STEC_CORRECTION message -/// -/// A full set of STEC information will likely span multiple SBP messages, -/// since SBP message a limited to 255 bytes. The header is used to tie -/// multiple SBP messages into a sequence. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct STECHeader { - /// Unique identifier of the tile set this tile belongs to. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_set_id")))] - pub tile_set_id: u16, - /// Unique identifier of this tile in the tile set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tile_id")))] - pub tile_id: u16, - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// Number of messages in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] - pub num_msgs: u8, - /// Position of this message in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] - pub seq_num: u8, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR atmospheric correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] - pub iod_atmo: u8, -} +pub mod stec_residual { + #![allow(unused_imports)] -impl WireFormat for STECHeader { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tile_set_id) - + WireFormat::len(&self.tile_id) - + WireFormat::len(&self.time) - + WireFormat::len(&self.num_msgs) - + WireFormat::len(&self.seq_num) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_atmo) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tile_set_id, buf); - WireFormat::write(&self.tile_id, buf); - WireFormat::write(&self.time, buf); - WireFormat::write(&self.num_msgs, buf); - WireFormat::write(&self.seq_num, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_atmo, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - STECHeader { - tile_set_id: WireFormat::parse_unchecked(buf), - tile_id: WireFormat::parse_unchecked(buf), - time: WireFormat::parse_unchecked(buf), - num_msgs: WireFormat::parse_unchecked(buf), - seq_num: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_atmo: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// None + /// + /// STEC residual (mean and standard deviation) for the given satellite at the + /// grid point. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct STECResidual { + /// space vehicle identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] + pub sv_id: SvId, + /// STEC residual + #[cfg_attr(feature = "serde", serde(rename(serialize = "residual")))] + pub residual: i16, + /// stddev + #[cfg_attr(feature = "serde", serde(rename(serialize = "stddev")))] + pub stddev: u8, + } + + impl WireFormat for STECResidual { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sv_id) + + WireFormat::len(&self.residual) + + WireFormat::len(&self.stddev) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sv_id, buf); + WireFormat::write(&self.residual, buf); + WireFormat::write(&self.stddev, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + STECResidual { + sv_id: WireFormat::parse_unchecked(buf), + residual: WireFormat::parse_unchecked(buf), + stddev: WireFormat::parse_unchecked(buf), + } } } } -/// Header for MSG_SSR_STEC_CORRECTION_DEP message -/// -/// A full set of STEC information will likely span multiple SBP messages, -/// since SBP message a limited to 255 bytes. The header is used to tie -/// multiple SBP messages into a sequence. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct STECHeaderDepA { - /// GNSS reference time of the correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: GpsTimeSec, - /// Number of messages in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_msgs")))] - pub num_msgs: u8, - /// Position of this message in the dataset - #[cfg_attr(feature = "serde", serde(rename(serialize = "seq_num")))] - pub seq_num: u8, - /// Update interval between consecutive corrections. Encoded following RTCM - /// DF391 specification. - #[cfg_attr(feature = "serde", serde(rename(serialize = "update_interval")))] - pub update_interval: u8, - /// IOD of the SSR atmospheric correction - #[cfg_attr(feature = "serde", serde(rename(serialize = "iod_atmo")))] - pub iod_atmo: u8, -} +pub mod stec_residual_no_std { + #![allow(unused_imports)] -impl WireFormat for STECHeaderDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.num_msgs) - + WireFormat::len(&self.seq_num) - + WireFormat::len(&self.update_interval) - + WireFormat::len(&self.iod_atmo) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.num_msgs, buf); - WireFormat::write(&self.seq_num, buf); - WireFormat::write(&self.update_interval, buf); - WireFormat::write(&self.iod_atmo, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - STECHeaderDepA { - time: WireFormat::parse_unchecked(buf), - num_msgs: WireFormat::parse_unchecked(buf), - seq_num: WireFormat::parse_unchecked(buf), - update_interval: WireFormat::parse_unchecked(buf), - iod_atmo: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// None + /// + /// STEC residual for the given satellite at the grid point. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct STECResidualNoStd { + /// space vehicle identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] + pub sv_id: SvId, + /// STEC residual + #[cfg_attr(feature = "serde", serde(rename(serialize = "residual")))] + pub residual: i16, + } + + impl WireFormat for STECResidualNoStd { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sv_id) + WireFormat::len(&self.residual) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sv_id, buf); + WireFormat::write(&self.residual, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + STECResidualNoStd { + sv_id: WireFormat::parse_unchecked(buf), + residual: WireFormat::parse_unchecked(buf), + } } } } -/// None -/// -/// STEC residual (mean and standard deviation) for the given satellite at the -/// grid point. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct STECResidual { - /// space vehicle identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] - pub sv_id: SvId, - /// STEC residual - #[cfg_attr(feature = "serde", serde(rename(serialize = "residual")))] - pub residual: i16, - /// stddev - #[cfg_attr(feature = "serde", serde(rename(serialize = "stddev")))] - pub stddev: u8, -} +pub mod stec_sat_element { + #![allow(unused_imports)] -impl WireFormat for STECResidual { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sv_id) - + WireFormat::len(&self.residual) - + WireFormat::len(&self.stddev) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sv_id, buf); - WireFormat::write(&self.residual, buf); - WireFormat::write(&self.stddev, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - STECResidual { - sv_id: WireFormat::parse_unchecked(buf), - residual: WireFormat::parse_unchecked(buf), - stddev: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// None + /// + /// STEC polynomial for the given satellite. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct STECSatElement { + /// Unique space vehicle identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] + pub sv_id: SvId, + /// Quality of the STEC data. Encoded following RTCM DF389 specification but + /// in units of TECU instead of m. + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_quality_indicator")))] + pub stec_quality_indicator: u8, + /// Coefficients of the STEC polynomial in the order of C00, C01, C10, C11 + #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_coeff")))] + pub stec_coeff: [i16; 4], + } + + impl WireFormat for STECSatElement { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + <[i16; 4] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sv_id) + + WireFormat::len(&self.stec_quality_indicator) + + WireFormat::len(&self.stec_coeff) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sv_id, buf); + WireFormat::write(&self.stec_quality_indicator, buf); + WireFormat::write(&self.stec_coeff, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + STECSatElement { + sv_id: WireFormat::parse_unchecked(buf), + stec_quality_indicator: WireFormat::parse_unchecked(buf), + stec_coeff: WireFormat::parse_unchecked(buf), + } } } } -/// None -/// -/// STEC residual for the given satellite at the grid point. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct STECResidualNoStd { - /// space vehicle identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] - pub sv_id: SvId, - /// STEC residual - #[cfg_attr(feature = "serde", serde(rename(serialize = "residual")))] - pub residual: i16, -} +pub mod satellite_apc { + #![allow(unused_imports)] -impl WireFormat for STECResidualNoStd { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sv_id) + WireFormat::len(&self.residual) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sv_id, buf); - WireFormat::write(&self.residual, buf); + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Antenna phase center correction + /// + /// Contains phase center offset and elevation variation corrections for one + /// signal on a satellite. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct SatelliteAPC { + /// GNSS signal identifier (16 bit) + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Additional satellite information + #[cfg_attr(feature = "serde", serde(rename(serialize = "sat_info")))] + pub sat_info: u8, + /// Satellite Code, as defined by IGS. Typically the space vehicle number. + #[cfg_attr(feature = "serde", serde(rename(serialize = "svn")))] + pub svn: u16, + /// Mean phase center offset, X Y and Z axes. See IGS ANTEX file format + /// description for coordinate system definition. + #[cfg_attr(feature = "serde", serde(rename(serialize = "pco")))] + pub pco: [i16; 3], + /// Elevation dependent phase center variations. First element is 0 degrees + /// separation from the Z axis, subsequent elements represent elevation + /// variations in 1 degree increments. + #[cfg_attr(feature = "serde", serde(rename(serialize = "pcv")))] + pub pcv: [i8; 21], + } + + impl SatelliteAPC { + /// Gets the [SatelliteType][self::SatelliteType] stored in the `sat_info` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SatelliteType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SatelliteType` were added. + pub fn satellite_type(&self) -> Result { + get_bit_range!(self.sat_info, u8, u8, 4, 0).try_into() + } + + /// Set the bitrange corresponding to the [SatelliteType][SatelliteType] of the `sat_info` bitfield. + pub fn set_satellite_type(&mut self, satellite_type: SatelliteType) { + set_bit_range!(&mut self.sat_info, satellite_type, u8, u8, 4, 0); + } } - fn parse_unchecked(buf: &mut B) -> Self { - STECResidualNoStd { - sv_id: WireFormat::parse_unchecked(buf), - residual: WireFormat::parse_unchecked(buf), + + impl WireFormat for SatelliteAPC { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + <[i16; 3] as WireFormat>::MIN_LEN + + <[i8; 21] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + + WireFormat::len(&self.sat_info) + + WireFormat::len(&self.svn) + + WireFormat::len(&self.pco) + + WireFormat::len(&self.pcv) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.sat_info, buf); + WireFormat::write(&self.svn, buf); + WireFormat::write(&self.pco, buf); + WireFormat::write(&self.pcv, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + SatelliteAPC { + sid: WireFormat::parse_unchecked(buf), + sat_info: WireFormat::parse_unchecked(buf), + svn: WireFormat::parse_unchecked(buf), + pco: WireFormat::parse_unchecked(buf), + pcv: WireFormat::parse_unchecked(buf), + } } } -} -/// None -/// -/// STEC polynomial for the given satellite. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct STECSatElement { - /// Unique space vehicle identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sv_id")))] - pub sv_id: SvId, - /// Quality of the STEC data. Encoded following RTCM DF389 specification but - /// in units of TECU instead of m. - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_quality_indicator")))] - pub stec_quality_indicator: u8, - /// Coefficients of the STEC polynomial in the order of C00, C01, C10, C11 - #[cfg_attr(feature = "serde", serde(rename(serialize = "stec_coeff")))] - pub stec_coeff: [i16; 4], -} + /// Satellite Type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SatelliteType { + /// Unknown Type + UnknownType = 0, -impl WireFormat for STECSatElement { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + <[i16; 4] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sv_id) - + WireFormat::len(&self.stec_quality_indicator) - + WireFormat::len(&self.stec_coeff) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sv_id, buf); - WireFormat::write(&self.stec_quality_indicator, buf); - WireFormat::write(&self.stec_coeff, buf); + /// GPS I + GpsI = 1, + + /// GPS II + GpsIi = 2, + + /// GPS IIA + GpsIia = 3, + + /// GPS IIR + GpsIir = 4, + + /// GPS IIF + GpsIif = 5, + + /// GPS III + GpsIii = 6, + + /// GLONASS + GLONASS = 7, + + /// GLONASS M + GlonassM = 8, + + /// GLONASS K1 + GlonassK1 = 9, + + /// GALILEO + GALILEO = 10, + + /// BEIDOU 2G + Beidou2G = 11, + + /// BEIDOU 2I + Beidou2I = 12, + + /// BEIDOU 2M + Beidou2M = 13, + + /// BEIDOU 3M, SECM + Beidou3MSecm = 14, + + /// BEIDOU 3G, SECM + Beidou3GSecm = 15, + + /// BEIDOU 3M, CAST + Beidou3MCast = 16, + + /// BEIDOU 3G, CAST + Beidou3GCast = 17, + + /// BEIDOU 3I, CAST + Beidou3ICast = 18, + + /// QZSS + QZSS = 19, } - fn parse_unchecked(buf: &mut B) -> Self { - STECSatElement { - sv_id: WireFormat::parse_unchecked(buf), - stec_quality_indicator: WireFormat::parse_unchecked(buf), - stec_coeff: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for SatelliteType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SatelliteType::UnknownType => f.write_str("Unknown Type"), + SatelliteType::GpsI => f.write_str("GPS I"), + SatelliteType::GpsIi => f.write_str("GPS II"), + SatelliteType::GpsIia => f.write_str("GPS IIA"), + SatelliteType::GpsIir => f.write_str("GPS IIR"), + SatelliteType::GpsIif => f.write_str("GPS IIF"), + SatelliteType::GpsIii => f.write_str("GPS III"), + SatelliteType::GLONASS => f.write_str("GLONASS"), + SatelliteType::GlonassM => f.write_str("GLONASS M"), + SatelliteType::GlonassK1 => f.write_str("GLONASS K1"), + SatelliteType::GALILEO => f.write_str("GALILEO"), + SatelliteType::Beidou2G => f.write_str("BEIDOU 2G"), + SatelliteType::Beidou2I => f.write_str("BEIDOU 2I"), + SatelliteType::Beidou2M => f.write_str("BEIDOU 2M"), + SatelliteType::Beidou3MSecm => f.write_str("BEIDOU 3M, SECM"), + SatelliteType::Beidou3GSecm => f.write_str("BEIDOU 3G, SECM"), + SatelliteType::Beidou3MCast => f.write_str("BEIDOU 3M, CAST"), + SatelliteType::Beidou3GCast => f.write_str("BEIDOU 3G, CAST"), + SatelliteType::Beidou3ICast => f.write_str("BEIDOU 3I, CAST"), + SatelliteType::QZSS => f.write_str("QZSS"), + } } } -} -/// Antenna phase center correction -/// -/// Contains phase center offset and elevation variation corrections for one -/// signal on a satellite. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct SatelliteAPC { - /// GNSS signal identifier (16 bit) - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Additional satellite information - #[cfg_attr(feature = "serde", serde(rename(serialize = "sat_info")))] - pub sat_info: u8, - /// Satellite Code, as defined by IGS. Typically the space vehicle number. - #[cfg_attr(feature = "serde", serde(rename(serialize = "svn")))] - pub svn: u16, - /// Mean phase center offset, X Y and Z axes. See IGS ANTEX file format - /// description for coordinate system definition. - #[cfg_attr(feature = "serde", serde(rename(serialize = "pco")))] - pub pco: [i16; 3], - /// Elevation dependent phase center variations. First element is 0 degrees - /// separation from the Z axis, subsequent elements represent elevation - /// variations in 1 degree increments. - #[cfg_attr(feature = "serde", serde(rename(serialize = "pcv")))] - pub pcv: [i8; 21], -} - -impl WireFormat for SatelliteAPC { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + <[i16; 3] as WireFormat>::MIN_LEN - + <[i8; 21] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) - + WireFormat::len(&self.sat_info) - + WireFormat::len(&self.svn) - + WireFormat::len(&self.pco) - + WireFormat::len(&self.pcv) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.sat_info, buf); - WireFormat::write(&self.svn, buf); - WireFormat::write(&self.pco, buf); - WireFormat::write(&self.pcv, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - SatelliteAPC { - sid: WireFormat::parse_unchecked(buf), - sat_info: WireFormat::parse_unchecked(buf), - svn: WireFormat::parse_unchecked(buf), - pco: WireFormat::parse_unchecked(buf), - pcv: WireFormat::parse_unchecked(buf), + impl TryFrom for SatelliteType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SatelliteType::UnknownType), + 1 => Ok(SatelliteType::GpsI), + 2 => Ok(SatelliteType::GpsIi), + 3 => Ok(SatelliteType::GpsIia), + 4 => Ok(SatelliteType::GpsIir), + 5 => Ok(SatelliteType::GpsIif), + 6 => Ok(SatelliteType::GpsIii), + 7 => Ok(SatelliteType::GLONASS), + 8 => Ok(SatelliteType::GlonassM), + 9 => Ok(SatelliteType::GlonassK1), + 10 => Ok(SatelliteType::GALILEO), + 11 => Ok(SatelliteType::Beidou2G), + 12 => Ok(SatelliteType::Beidou2I), + 13 => Ok(SatelliteType::Beidou2M), + 14 => Ok(SatelliteType::Beidou3MSecm), + 15 => Ok(SatelliteType::Beidou3GSecm), + 16 => Ok(SatelliteType::Beidou3MCast), + 17 => Ok(SatelliteType::Beidou3GCast), + 18 => Ok(SatelliteType::Beidou3ICast), + 19 => Ok(SatelliteType::QZSS), + i => Err(i), + } } } } -/// None -/// -/// Troposphere vertical delays (mean and standard deviation) at the grid -/// point. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TroposphericDelayCorrection { - /// Hydrostatic vertical delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "hydro")))] - pub hydro: i16, - /// Wet vertical delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "wet")))] - pub wet: i8, - /// stddev - #[cfg_attr(feature = "serde", serde(rename(serialize = "stddev")))] - pub stddev: u8, -} +pub mod tropospheric_delay_correction { + #![allow(unused_imports)] -impl WireFormat for TroposphericDelayCorrection { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.hydro) + WireFormat::len(&self.wet) + WireFormat::len(&self.stddev) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.hydro, buf); - WireFormat::write(&self.wet, buf); - WireFormat::write(&self.stddev, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - TroposphericDelayCorrection { - hydro: WireFormat::parse_unchecked(buf), - wet: WireFormat::parse_unchecked(buf), - stddev: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// None + /// + /// Troposphere vertical delays (mean and standard deviation) at the grid + /// point. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TroposphericDelayCorrection { + /// Hydrostatic vertical delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "hydro")))] + pub hydro: i16, + /// Wet vertical delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "wet")))] + pub wet: i8, + /// stddev + #[cfg_attr(feature = "serde", serde(rename(serialize = "stddev")))] + pub stddev: u8, + } + + impl WireFormat for TroposphericDelayCorrection { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.hydro) + + WireFormat::len(&self.wet) + + WireFormat::len(&self.stddev) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.hydro, buf); + WireFormat::write(&self.wet, buf); + WireFormat::write(&self.stddev, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TroposphericDelayCorrection { + hydro: WireFormat::parse_unchecked(buf), + wet: WireFormat::parse_unchecked(buf), + stddev: WireFormat::parse_unchecked(buf), + } } } } -/// None -/// -/// Troposphere vertical delays at the grid point. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TroposphericDelayCorrectionNoStd { - /// Hydrostatic vertical delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "hydro")))] - pub hydro: i16, - /// Wet vertical delay - #[cfg_attr(feature = "serde", serde(rename(serialize = "wet")))] - pub wet: i8, -} +pub mod tropospheric_delay_correction_no_std { + #![allow(unused_imports)] -impl WireFormat for TroposphericDelayCorrectionNoStd { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.hydro) + WireFormat::len(&self.wet) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.hydro, buf); - WireFormat::write(&self.wet, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - TroposphericDelayCorrectionNoStd { - hydro: WireFormat::parse_unchecked(buf), - wet: WireFormat::parse_unchecked(buf), + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// None + /// + /// Troposphere vertical delays at the grid point. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TroposphericDelayCorrectionNoStd { + /// Hydrostatic vertical delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "hydro")))] + pub hydro: i16, + /// Wet vertical delay + #[cfg_attr(feature = "serde", serde(rename(serialize = "wet")))] + pub wet: i8, + } + + impl WireFormat for TroposphericDelayCorrectionNoStd { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.hydro) + WireFormat::len(&self.wet) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.hydro, buf); + WireFormat::write(&self.wet, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TroposphericDelayCorrectionNoStd { + hydro: WireFormat::parse_unchecked(buf), + wet: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/system.rs b/rust/sbp/src/messages/system.rs index e03de5f0b5..596d3a050e 100644 --- a/rust/sbp/src/messages/system.rs +++ b/rust/sbp/src/messages/system.rs @@ -13,1082 +13,2624 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Standardized system messages from Swift Navigation devices. +pub use msg_csac_telemetry::MsgCsacTelemetry; +pub use msg_csac_telemetry_labels::MsgCsacTelemetryLabels; +pub use msg_dgnss_status::MsgDgnssStatus; +pub use msg_gnss_time_offset::MsgGnssTimeOffset; +pub use msg_group_meta::MsgGroupMeta; +pub use msg_heartbeat::MsgHeartbeat; +pub use msg_ins_status::MsgInsStatus; +pub use msg_ins_updates::MsgInsUpdates; +pub use msg_pps_time::MsgPpsTime; +pub use msg_sensor_aid_event::MsgSensorAidEvent; +pub use msg_startup::MsgStartup; +pub use msg_status_report::MsgStatusReport; +pub use sub_system_report::SubSystemReport; + +pub mod msg_csac_telemetry { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Experimental telemetry message + /// + /// The CSAC telemetry message has an implementation defined telemetry string + /// from a device. It is not produced or available on general Swift Products. + /// It is intended to be a low rate message for status purposes. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCsacTelemetry { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Index representing the type of telemetry in use. It is implementation + /// defined. + #[cfg_attr(feature = "serde", serde(rename(serialize = "id")))] + pub id: u8, + /// Comma separated list of values as defined by the index + #[cfg_attr(feature = "serde", serde(rename(serialize = "telemetry")))] + pub telemetry: SbpString, Unterminated>, + } + + impl ConcreteMessage for MsgCsacTelemetry { + const MESSAGE_TYPE: u16 = 65284; + const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY"; + } + + impl SbpMessage for MsgCsacTelemetry { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } -use super::lib::*; - -/// Experimental telemetry message -/// -/// The CSAC telemetry message has an implementation defined telemetry string -/// from a device. It is not produced or available on general Swift Products. -/// It is intended to be a low rate message for status purposes. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCsacTelemetry { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Index representing the type of telemetry in use. It is implementation - /// defined. - #[cfg_attr(feature = "serde", serde(rename(serialize = "id")))] - pub id: u8, - /// Comma separated list of values as defined by the index - #[cfg_attr(feature = "serde", serde(rename(serialize = "telemetry")))] - pub telemetry: SbpString, Unterminated>, + impl TryFrom for MsgCsacTelemetry { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCsacTelemetry(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgCsacTelemetry { + const MIN_LEN: usize = + ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.id) + WireFormat::len(&self.telemetry) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.id, buf); + WireFormat::write(&self.telemetry, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCsacTelemetry { + sender_id: None, + id: WireFormat::parse_unchecked(buf), + telemetry: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgCsacTelemetry { - const MESSAGE_TYPE: u16 = 65284; - const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY"; +pub mod msg_csac_telemetry_labels { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Experimental telemetry message labels + /// + /// The CSAC telemetry message provides labels for each member of the string + /// produced by MSG_CSAC_TELEMETRY. It should be provided by a device at a + /// lower rate than the MSG_CSAC_TELEMETRY. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgCsacTelemetryLabels { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Index representing the type of telemetry in use. It is implementation + /// defined. + #[cfg_attr(feature = "serde", serde(rename(serialize = "id")))] + pub id: u8, + /// Comma separated list of telemetry field values + #[cfg_attr(feature = "serde", serde(rename(serialize = "telemetry_labels")))] + pub telemetry_labels: SbpString, Unterminated>, + } + + impl ConcreteMessage for MsgCsacTelemetryLabels { + const MESSAGE_TYPE: u16 = 65285; + const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY_LABELS"; + } + + impl SbpMessage for MsgCsacTelemetryLabels { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgCsacTelemetryLabels { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgCsacTelemetryLabels(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgCsacTelemetryLabels { + const MIN_LEN: usize = + ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.id) + WireFormat::len(&self.telemetry_labels) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.id, buf); + WireFormat::write(&self.telemetry_labels, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgCsacTelemetryLabels { + sender_id: None, + id: WireFormat::parse_unchecked(buf), + telemetry_labels: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgCsacTelemetry { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_dgnss_status { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Status of received corrections + /// + /// This message provides information about the receipt of Differential + /// corrections. It is expected to be sent with each receipt of a complete + /// corrections packet. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgDgnssStatus { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// Latency of observation receipt + #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] + pub latency: u16, + /// Number of signals from base station + #[cfg_attr(feature = "serde", serde(rename(serialize = "num_signals")))] + pub num_signals: u8, + /// Corrections source string + #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] + pub source: SbpString, Unterminated>, + } + + impl MsgDgnssStatus { + /// Gets the [DifferentialType][self::DifferentialType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `DifferentialType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `DifferentialType` were added. + pub fn differential_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 0).try_into() + } + + /// Set the bitrange corresponding to the [DifferentialType][DifferentialType] of the `flags` bitfield. + pub fn set_differential_type(&mut self, differential_type: DifferentialType) { + set_bit_range!(&mut self.flags, differential_type, u8, u8, 3, 0); + } + } + + impl ConcreteMessage for MsgDgnssStatus { + const MESSAGE_TYPE: u16 = 65282; + const MESSAGE_NAME: &'static str = "MSG_DGNSS_STATUS"; + } + + impl SbpMessage for MsgDgnssStatus { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for MsgDgnssStatus { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgDgnssStatus(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl WireFormat for MsgDgnssStatus { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + , Unterminated> as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + + WireFormat::len(&self.latency) + + WireFormat::len(&self.num_signals) + + WireFormat::len(&self.source) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.latency, buf); + WireFormat::write(&self.num_signals, buf); + WireFormat::write(&self.source, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgDgnssStatus { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + latency: WireFormat::parse_unchecked(buf), + num_signals: WireFormat::parse_unchecked(buf), + source: WireFormat::parse_unchecked(buf), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Differential type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum DifferentialType { + /// Invalid + Invalid = 0, + + /// Code Difference + CodeDifference = 1, + + /// RTK + RTK = 2, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for DifferentialType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DifferentialType::Invalid => f.write_str("Invalid"), + DifferentialType::CodeDifference => f.write_str("Code Difference"), + DifferentialType::RTK => f.write_str("RTK"), + } + } } -} -impl TryFrom for MsgCsacTelemetry { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCsacTelemetry(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for DifferentialType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(DifferentialType::Invalid), + 1 => Ok(DifferentialType::CodeDifference), + 2 => Ok(DifferentialType::RTK), + i => Err(i), + } } } } -impl WireFormat for MsgCsacTelemetry { - const MIN_LEN: usize = - ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.id) + WireFormat::len(&self.telemetry) +pub mod msg_gnss_time_offset { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Offset of the local time with respect to GNSS time + /// + /// The GNSS time offset message contains the information that is needed to + /// translate messages tagged with a local timestamp (e.g. IMU or wheeltick + /// messages) to GNSS time for the sender producing this message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGnssTimeOffset { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Weeks portion of the time offset + #[cfg_attr(feature = "serde", serde(rename(serialize = "weeks")))] + pub weeks: i16, + /// Milliseconds portion of the time offset + #[cfg_attr(feature = "serde", serde(rename(serialize = "milliseconds")))] + pub milliseconds: i32, + /// Microseconds portion of the time offset + #[cfg_attr(feature = "serde", serde(rename(serialize = "microseconds")))] + pub microseconds: i16, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl ConcreteMessage for MsgGnssTimeOffset { + const MESSAGE_TYPE: u16 = 65287; + const MESSAGE_NAME: &'static str = "MSG_GNSS_TIME_OFFSET"; + } + + impl SbpMessage for MsgGnssTimeOffset { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.id, buf); - WireFormat::write(&self.telemetry, buf); + + impl TryFrom for MsgGnssTimeOffset { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGnssTimeOffset(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCsacTelemetry { - sender_id: None, - id: WireFormat::parse_unchecked(buf), - telemetry: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgGnssTimeOffset { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.weeks) + + WireFormat::len(&self.milliseconds) + + WireFormat::len(&self.microseconds) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.weeks, buf); + WireFormat::write(&self.milliseconds, buf); + WireFormat::write(&self.microseconds, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGnssTimeOffset { + sender_id: None, + weeks: WireFormat::parse_unchecked(buf), + milliseconds: WireFormat::parse_unchecked(buf), + microseconds: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } } -/// Experimental telemetry message labels -/// -/// The CSAC telemetry message provides labels for each member of the string -/// produced by MSG_CSAC_TELEMETRY. It should be provided by a device at a -/// lower rate than the MSG_CSAC_TELEMETRY. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgCsacTelemetryLabels { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Index representing the type of telemetry in use. It is implementation - /// defined. - #[cfg_attr(feature = "serde", serde(rename(serialize = "id")))] - pub id: u8, - /// Comma separated list of telemetry field values - #[cfg_attr(feature = "serde", serde(rename(serialize = "telemetry_labels")))] - pub telemetry_labels: SbpString, Unterminated>, -} +pub mod msg_group_meta { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Solution Group Metadata + /// + /// This leading message lists the time metadata of the Solution Group. It + /// also lists the atomic contents (i.e. types of messages included) of the + /// Solution Group. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgGroupMeta { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Id of the Msgs Group, 0 is Unknown, 1 is Bestpos, 2 is Gnss + #[cfg_attr(feature = "serde", serde(rename(serialize = "group_id")))] + pub group_id: u8, + /// Status flags (reserved) + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// Size of list group_msgs + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_group_msgs")))] + pub n_group_msgs: u8, + /// An in-order list of message types included in the Solution Group, + /// including GROUP_META itself + #[cfg_attr(feature = "serde", serde(rename(serialize = "group_msgs")))] + pub group_msgs: Vec, + } + + impl MsgGroupMeta { + /// Gets the [SolutionGroupType][self::SolutionGroupType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SolutionGroupType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SolutionGroupType` were added. + pub fn solution_group_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } -impl ConcreteMessage for MsgCsacTelemetryLabels { - const MESSAGE_TYPE: u16 = 65285; - const MESSAGE_NAME: &'static str = "MSG_CSAC_TELEMETRY_LABELS"; -} + /// Set the bitrange corresponding to the [SolutionGroupType][SolutionGroupType] of the `flags` bitfield. + pub fn set_solution_group_type(&mut self, solution_group_type: SolutionGroupType) { + set_bit_range!(&mut self.flags, solution_group_type, u8, u8, 1, 0); + } + } -impl SbpMessage for MsgCsacTelemetryLabels { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl ConcreteMessage for MsgGroupMeta { + const MESSAGE_TYPE: u16 = 65290; + const MESSAGE_NAME: &'static str = "MSG_GROUP_META"; } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl SbpMessage for MsgGroupMeta { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MsgGroupMeta { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgGroupMeta(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgGroupMeta { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.group_id) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.n_group_msgs) + + WireFormat::len(&self.group_msgs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.group_id, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.n_group_msgs, buf); + WireFormat::write(&self.group_msgs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgGroupMeta { + sender_id: None, + group_id: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + n_group_msgs: WireFormat::parse_unchecked(buf), + group_msgs: WireFormat::parse_unchecked(buf), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Solution Group type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SolutionGroupType { + /// None (invalid) + None = 0, + + /// GNSS only + GnssOnly = 1, + + /// GNSS+INS (Fuzed) + GnssINS = 2, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for SolutionGroupType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SolutionGroupType::None => f.write_str("None (invalid)"), + SolutionGroupType::GnssOnly => f.write_str("GNSS only"), + SolutionGroupType::GnssINS => f.write_str("GNSS+INS (Fuzed)"), + } + } } -} -impl TryFrom for MsgCsacTelemetryLabels { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgCsacTelemetryLabels(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for SolutionGroupType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SolutionGroupType::None), + 1 => Ok(SolutionGroupType::GnssOnly), + 2 => Ok(SolutionGroupType::GnssINS), + i => Err(i), + } } } } -impl WireFormat for MsgCsacTelemetryLabels { - const MIN_LEN: usize = - ::MIN_LEN + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.id) + WireFormat::len(&self.telemetry_labels) +pub mod msg_heartbeat { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// System heartbeat message + /// + /// The heartbeat message is sent periodically to inform the host or other + /// attached devices that the system is running. It is used to monitor system + /// malfunctions. It also contains status flags that indicate to the host the + /// status of the system and whether it is operating correctly. Currently, the + /// expected heartbeat interval is 1 sec. + /// + /// The system error flag is used to indicate that an error has occurred in + /// the system. To determine the source of the error, the remaining error + /// flags should be inspected. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgHeartbeat { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgHeartbeat { + /// Gets the [ExternalAntennaPresent][self::ExternalAntennaPresent] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ExternalAntennaPresent` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ExternalAntennaPresent` were added. + pub fn external_antenna_present(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 31, 31).try_into() + } + + /// Set the bitrange corresponding to the [ExternalAntennaPresent][ExternalAntennaPresent] of the `flags` bitfield. + pub fn set_external_antenna_present( + &mut self, + external_antenna_present: ExternalAntennaPresent, + ) { + set_bit_range!(&mut self.flags, external_antenna_present, u32, u8, 31, 31); + } + + /// Gets the [ExternalAntennaShort][self::ExternalAntennaShort] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ExternalAntennaShort` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ExternalAntennaShort` were added. + pub fn external_antenna_short(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 30, 30).try_into() + } + + /// Set the bitrange corresponding to the [ExternalAntennaShort][ExternalAntennaShort] of the `flags` bitfield. + pub fn set_external_antenna_short(&mut self, external_antenna_short: ExternalAntennaShort) { + set_bit_range!(&mut self.flags, external_antenna_short, u32, u8, 30, 30); + } + + /// Gets the `sbp_major_protocol_version_number` stored in `flags`. + pub fn sbp_major_protocol_version_number(&self) -> u8 { + get_bit_range!(self.flags, u32, u8, 23, 16) + } + + /// Sets the `sbp_major_protocol_version_number` bitrange of `flags`. + pub fn set_sbp_major_protocol_version_number( + &mut self, + sbp_major_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.flags, + sbp_major_protocol_version_number, + u32, + u8, + 23, + 16 + ); + } + + /// Gets the `sbp_minor_protocol_version_number` stored in `flags`. + pub fn sbp_minor_protocol_version_number(&self) -> u8 { + get_bit_range!(self.flags, u32, u8, 15, 8) + } + + /// Sets the `sbp_minor_protocol_version_number` bitrange of `flags`. + pub fn set_sbp_minor_protocol_version_number( + &mut self, + sbp_minor_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.flags, + sbp_minor_protocol_version_number, + u32, + u8, + 15, + 8 + ); + } + + /// Gets the [SwiftNapError][self::SwiftNapError] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SwiftNapError` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SwiftNapError` were added. + pub fn swift_nap_error(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 2, 2).try_into() + } + + /// Set the bitrange corresponding to the [SwiftNapError][SwiftNapError] of the `flags` bitfield. + pub fn set_swift_nap_error(&mut self, swift_nap_error: SwiftNapError) { + set_bit_range!(&mut self.flags, swift_nap_error, u32, u8, 2, 2); + } + + /// Gets the [IoError][self::IoError] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `IoError` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `IoError` were added. + pub fn io_error(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 1, 1).try_into() + } + + /// Set the bitrange corresponding to the [IoError][IoError] of the `flags` bitfield. + pub fn set_io_error(&mut self, io_error: IoError) { + set_bit_range!(&mut self.flags, io_error, u32, u8, 1, 1); + } + + /// Gets the [SystemErrorFlag][self::SystemErrorFlag] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SystemErrorFlag` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SystemErrorFlag` were added. + pub fn system_error_flag(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 0, 0).try_into() + } + + /// Set the bitrange corresponding to the [SystemErrorFlag][SystemErrorFlag] of the `flags` bitfield. + pub fn set_system_error_flag(&mut self, system_error_flag: SystemErrorFlag) { + set_bit_range!(&mut self.flags, system_error_flag, u32, u8, 0, 0); + } + } + + impl ConcreteMessage for MsgHeartbeat { + const MESSAGE_TYPE: u16 = 65535; + const MESSAGE_NAME: &'static str = "MSG_HEARTBEAT"; } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.id, buf); - WireFormat::write(&self.telemetry_labels, buf); + + impl SbpMessage for MsgHeartbeat { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgCsacTelemetryLabels { - sender_id: None, - id: WireFormat::parse_unchecked(buf), - telemetry_labels: WireFormat::parse_unchecked(buf), + + impl TryFrom for MsgHeartbeat { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgHeartbeat(m) => Ok(m), + _ => Err(TryFromSbpError), + } } } -} -/// Status of received corrections -/// -/// This message provides information about the receipt of Differential -/// corrections. It is expected to be sent with each receipt of a complete -/// corrections packet. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgDgnssStatus { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// Latency of observation receipt - #[cfg_attr(feature = "serde", serde(rename(serialize = "latency")))] - pub latency: u16, - /// Number of signals from base station - #[cfg_attr(feature = "serde", serde(rename(serialize = "num_signals")))] - pub num_signals: u8, - /// Corrections source string - #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] - pub source: SbpString, Unterminated>, -} + impl WireFormat for MsgHeartbeat { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgHeartbeat { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + } + } + } -impl ConcreteMessage for MsgDgnssStatus { - const MESSAGE_TYPE: u16 = 65282; - const MESSAGE_NAME: &'static str = "MSG_DGNSS_STATUS"; -} + /// External antenna present + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ExternalAntennaPresent { + /// No external antenna detected + NoExternalAntennaDetected = 0, -impl SbpMessage for MsgDgnssStatus { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// External antenna is present + ExternalAntennaIsPresent = 1, } - fn sender_id(&self) -> Option { - self.sender_id + + impl std::fmt::Display for ExternalAntennaPresent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ExternalAntennaPresent::NoExternalAntennaDetected => { + f.write_str("No external antenna detected") + } + ExternalAntennaPresent::ExternalAntennaIsPresent => { + f.write_str("External antenna is present") + } + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for ExternalAntennaPresent { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ExternalAntennaPresent::NoExternalAntennaDetected), + 1 => Ok(ExternalAntennaPresent::ExternalAntennaIsPresent), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// External antenna short + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ExternalAntennaShort { + /// No short detected + NoShortDetected = 0, + + /// Short detected + ShortDetected = 1, } -} -impl TryFrom for MsgDgnssStatus { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgDgnssStatus(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for ExternalAntennaShort { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ExternalAntennaShort::NoShortDetected => f.write_str("No short detected"), + ExternalAntennaShort::ShortDetected => f.write_str("Short detected"), + } } } -} -impl WireFormat for MsgDgnssStatus { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + , Unterminated> as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) - + WireFormat::len(&self.latency) - + WireFormat::len(&self.num_signals) - + WireFormat::len(&self.source) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.latency, buf); - WireFormat::write(&self.num_signals, buf); - WireFormat::write(&self.source, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgDgnssStatus { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), - latency: WireFormat::parse_unchecked(buf), - num_signals: WireFormat::parse_unchecked(buf), - source: WireFormat::parse_unchecked(buf), + impl TryFrom for ExternalAntennaShort { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ExternalAntennaShort::NoShortDetected), + 1 => Ok(ExternalAntennaShort::ShortDetected), + i => Err(i), + } } } -} -/// Offset of the local time with respect to GNSS time -/// -/// The GNSS time offset message contains the information that is needed to -/// translate messages tagged with a local timestamp (e.g. IMU or wheeltick -/// messages) to GNSS time for the sender producing this message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGnssTimeOffset { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Weeks portion of the time offset - #[cfg_attr(feature = "serde", serde(rename(serialize = "weeks")))] - pub weeks: i16, - /// Milliseconds portion of the time offset - #[cfg_attr(feature = "serde", serde(rename(serialize = "milliseconds")))] - pub milliseconds: i32, - /// Microseconds portion of the time offset - #[cfg_attr(feature = "serde", serde(rename(serialize = "microseconds")))] - pub microseconds: i16, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + /// SwiftNAP Error + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SwiftNapError { + /// System Healthy + SystemHealthy = 0, -impl ConcreteMessage for MsgGnssTimeOffset { - const MESSAGE_TYPE: u16 = 65287; - const MESSAGE_NAME: &'static str = "MSG_GNSS_TIME_OFFSET"; -} + /// An error has occurred in the SwiftNAP + AnErrorHasOccurredInTheSwiftNap = 1, + } -impl SbpMessage for MsgGnssTimeOffset { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for SwiftNapError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SwiftNapError::SystemHealthy => f.write_str("System Healthy"), + SwiftNapError::AnErrorHasOccurredInTheSwiftNap => { + f.write_str("An error has occurred in the SwiftNAP") + } + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for SwiftNapError { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SwiftNapError::SystemHealthy), + 1 => Ok(SwiftNapError::AnErrorHasOccurredInTheSwiftNap), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// IO Error + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum IoError { + /// System Healthy + SystemHealthy = 0, + + /// An IO error has occurred + AnIoErrorHasOccurred = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for IoError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + IoError::SystemHealthy => f.write_str("System Healthy"), + IoError::AnIoErrorHasOccurred => f.write_str("An IO error has occurred"), + } + } + } + + impl TryFrom for IoError { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(IoError::SystemHealthy), + 1 => Ok(IoError::AnIoErrorHasOccurred), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// System Error Flag + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SystemErrorFlag { + /// System Healthy + SystemHealthy = 0, + + /// An error has occurred + AnErrorHasOccurred = 1, } -} -impl TryFrom for MsgGnssTimeOffset { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGnssTimeOffset(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for SystemErrorFlag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SystemErrorFlag::SystemHealthy => f.write_str("System Healthy"), + SystemErrorFlag::AnErrorHasOccurred => f.write_str("An error has occurred"), + } } } -} -impl WireFormat for MsgGnssTimeOffset { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.weeks) - + WireFormat::len(&self.milliseconds) - + WireFormat::len(&self.microseconds) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.weeks, buf); - WireFormat::write(&self.milliseconds, buf); - WireFormat::write(&self.microseconds, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGnssTimeOffset { - sender_id: None, - weeks: WireFormat::parse_unchecked(buf), - milliseconds: WireFormat::parse_unchecked(buf), - microseconds: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for SystemErrorFlag { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SystemErrorFlag::SystemHealthy), + 1 => Ok(SystemErrorFlag::AnErrorHasOccurred), + i => Err(i), + } } } } -/// Solution Group Metadata -/// -/// This leading message lists the time metadata of the Solution Group. It -/// also lists the atomic contents (i.e. types of messages included) of the -/// Solution Group. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgGroupMeta { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Id of the Msgs Group, 0 is Unknown, 1 is Bestpos, 2 is Gnss - #[cfg_attr(feature = "serde", serde(rename(serialize = "group_id")))] - pub group_id: u8, - /// Status flags (reserved) - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// Size of list group_msgs - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_group_msgs")))] - pub n_group_msgs: u8, - /// An in-order list of message types included in the Solution Group, - /// including GROUP_META itself - #[cfg_attr(feature = "serde", serde(rename(serialize = "group_msgs")))] - pub group_msgs: Vec, -} +pub mod msg_ins_status { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Inertial Navigation System status message + /// + /// The INS status message describes the state of the operation and + /// initialization of the inertial navigation system. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgInsStatus { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgInsStatus { + /// Gets the [InsType][self::InsType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsType` were added. + pub fn ins_type(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 31, 29).try_into() + } -impl ConcreteMessage for MsgGroupMeta { - const MESSAGE_TYPE: u16 = 65290; - const MESSAGE_NAME: &'static str = "MSG_GROUP_META"; -} + /// Set the bitrange corresponding to the [InsType][InsType] of the `flags` bitfield. + pub fn set_ins_type(&mut self, ins_type: InsType) { + set_bit_range!(&mut self.flags, ins_type, u32, u8, 31, 29); + } + + /// Gets the [MotionState][self::MotionState] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `MotionState` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `MotionState` were added. + pub fn motion_state(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 13, 11).try_into() + } + + /// Set the bitrange corresponding to the [MotionState][MotionState] of the `flags` bitfield. + pub fn set_motion_state(&mut self, motion_state: MotionState) { + set_bit_range!(&mut self.flags, motion_state, u32, u8, 13, 11); + } + + /// Gets the [OdometrySynch][self::OdometrySynch] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `OdometrySynch` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `OdometrySynch` were added. + pub fn odometry_synch(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 10, 10).try_into() + } + + /// Set the bitrange corresponding to the [OdometrySynch][OdometrySynch] of the `flags` bitfield. + pub fn set_odometry_synch(&mut self, odometry_synch: OdometrySynch) { + set_bit_range!(&mut self.flags, odometry_synch, u32, u8, 10, 10); + } + + /// Gets the [OdometryStatus][self::OdometryStatus] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `OdometryStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `OdometryStatus` were added. + pub fn odometry_status(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 9, 8).try_into() + } + + /// Set the bitrange corresponding to the [OdometryStatus][OdometryStatus] of the `flags` bitfield. + pub fn set_odometry_status(&mut self, odometry_status: OdometryStatus) { + set_bit_range!(&mut self.flags, odometry_status, u32, u8, 9, 8); + } -impl SbpMessage for MsgGroupMeta { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Gets the [InsError][self::InsError] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `InsError` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `InsError` were added. + pub fn ins_error(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 7, 4).try_into() + } + + /// Set the bitrange corresponding to the [InsError][InsError] of the `flags` bitfield. + pub fn set_ins_error(&mut self, ins_error: InsError) { + set_bit_range!(&mut self.flags, ins_error, u32, u8, 7, 4); + } + + /// Gets the [GnssFix][self::GnssFix] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `GnssFix` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `GnssFix` were added. + pub fn gnss_fix(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [GnssFix][GnssFix] of the `flags` bitfield. + pub fn set_gnss_fix(&mut self, gnss_fix: GnssFix) { + set_bit_range!(&mut self.flags, gnss_fix, u32, u8, 3, 3); + } + + /// Gets the [Mode][self::Mode] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Mode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `Mode` were added. + pub fn mode(&self) -> Result { + get_bit_range!(self.flags, u32, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [Mode][Mode] of the `flags` bitfield. + pub fn set_mode(&mut self, mode: Mode) { + set_bit_range!(&mut self.flags, mode, u32, u8, 2, 0); + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl ConcreteMessage for MsgInsStatus { + const MESSAGE_TYPE: u16 = 65283; + const MESSAGE_NAME: &'static str = "MSG_INS_STATUS"; } - fn sender_id(&self) -> Option { - self.sender_id + + impl SbpMessage for MsgInsStatus { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for MsgInsStatus { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgInsStatus(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgInsStatus { + const MIN_LEN: usize = ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgInsStatus { + sender_id: None, + flags: WireFormat::parse_unchecked(buf), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// INS Type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsType { + /// Smoothpose Loosely Coupled + SmoothposeLooselyCoupled = 0, + + /// Starling + Starling = 1, } -} -impl TryFrom for MsgGroupMeta { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgGroupMeta(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for InsType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsType::SmoothposeLooselyCoupled => f.write_str("Smoothpose Loosely Coupled"), + InsType::Starling => f.write_str("Starling"), + } } } -} -impl WireFormat for MsgGroupMeta { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.group_id) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.n_group_msgs) - + WireFormat::len(&self.group_msgs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.group_id, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.n_group_msgs, buf); - WireFormat::write(&self.group_msgs, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgGroupMeta { - sender_id: None, - group_id: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - n_group_msgs: WireFormat::parse_unchecked(buf), - group_msgs: WireFormat::parse_unchecked(buf), + impl TryFrom for InsType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(InsType::SmoothposeLooselyCoupled), + 1 => Ok(InsType::Starling), + i => Err(i), + } } } -} -/// System heartbeat message -/// -/// The heartbeat message is sent periodically to inform the host or other -/// attached devices that the system is running. It is used to monitor system -/// malfunctions. It also contains status flags that indicate to the host the -/// status of the system and whether it is operating correctly. Currently, the -/// expected heartbeat interval is 1 sec. -/// -/// The system error flag is used to indicate that an error has occurred in -/// the system. To determine the source of the error, the remaining error -/// flags should be inspected. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgHeartbeat { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} + /// Motion State + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum MotionState { + /// Unknown or Init + UnknownOrInit = 0, -impl ConcreteMessage for MsgHeartbeat { - const MESSAGE_TYPE: u16 = 65535; - const MESSAGE_NAME: &'static str = "MSG_HEARTBEAT"; -} + /// Arbitrary Motion + ArbitraryMotion = 1, + + /// Straight Motion + StraightMotion = 2, -impl SbpMessage for MsgHeartbeat { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Stationary + Stationary = 3, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for MotionState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MotionState::UnknownOrInit => f.write_str("Unknown or Init"), + MotionState::ArbitraryMotion => f.write_str("Arbitrary Motion"), + MotionState::StraightMotion => f.write_str("Straight Motion"), + MotionState::Stationary => f.write_str("Stationary"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for MotionState { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(MotionState::UnknownOrInit), + 1 => Ok(MotionState::ArbitraryMotion), + 2 => Ok(MotionState::StraightMotion), + 3 => Ok(MotionState::Stationary), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Odometry Synch + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum OdometrySynch { + /// Odometry timestamp nominal + OdometryTimestampNominal = 0, + + /// Odometry timestamp out of bounds + OdometryTimestampOutOfBounds = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for OdometrySynch { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OdometrySynch::OdometryTimestampNominal => { + f.write_str("Odometry timestamp nominal") + } + OdometrySynch::OdometryTimestampOutOfBounds => { + f.write_str("Odometry timestamp out of bounds") + } + } + } } -} -impl TryFrom for MsgHeartbeat { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgHeartbeat(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for OdometrySynch { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(OdometrySynch::OdometryTimestampNominal), + 1 => Ok(OdometrySynch::OdometryTimestampOutOfBounds), + i => Err(i), + } } } -} -impl WireFormat for MsgHeartbeat { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) + /// Odometry status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum OdometryStatus { + /// No Odometry + NoOdometry = 0, + + /// Odometry received within last second + OdometryReceivedWithinLastSecond = 1, + + /// Odometry not received within last second + OdometryNotReceivedWithinLastSecond = 2, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); + + impl std::fmt::Display for OdometryStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OdometryStatus::NoOdometry => f.write_str("No Odometry"), + OdometryStatus::OdometryReceivedWithinLastSecond => { + f.write_str("Odometry received within last second") + } + OdometryStatus::OdometryNotReceivedWithinLastSecond => { + f.write_str("Odometry not received within last second") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgHeartbeat { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), + + impl TryFrom for OdometryStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(OdometryStatus::NoOdometry), + 1 => Ok(OdometryStatus::OdometryReceivedWithinLastSecond), + 2 => Ok(OdometryStatus::OdometryNotReceivedWithinLastSecond), + i => Err(i), + } } } -} -/// Inertial Navigation System status message -/// -/// The INS status message describes the state of the operation and -/// initialization of the inertial navigation system. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgInsStatus { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} + /// INS Error + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum InsError { + /// IMU Data Error + ImuDataError = 1, -impl ConcreteMessage for MsgInsStatus { - const MESSAGE_TYPE: u16 = 65283; - const MESSAGE_NAME: &'static str = "MSG_INS_STATUS"; -} + /// INS License Error + InsLicenseError = 2, -impl SbpMessage for MsgInsStatus { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// IMU Calibration Data Error + ImuCalibrationDataError = 3, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for InsError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsError::ImuDataError => f.write_str("IMU Data Error"), + InsError::InsLicenseError => f.write_str("INS License Error"), + InsError::ImuCalibrationDataError => f.write_str("IMU Calibration Data Error"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for InsError { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 1 => Ok(InsError::ImuDataError), + 2 => Ok(InsError::InsLicenseError), + 3 => Ok(InsError::ImuCalibrationDataError), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// GNSS Fix + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum GnssFix { + /// No GNSS fix available + NoGnssFixAvailable = 0, + + /// GNSS fix + GnssFix = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for GnssFix { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GnssFix::NoGnssFixAvailable => f.write_str("No GNSS fix available"), + GnssFix::GnssFix => f.write_str("GNSS fix"), + } + } } -} -impl TryFrom for MsgInsStatus { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgInsStatus(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for GnssFix { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(GnssFix::NoGnssFixAvailable), + 1 => Ok(GnssFix::GnssFix), + i => Err(i), + } } } -} -impl WireFormat for MsgInsStatus { - const MIN_LEN: usize = ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.flags) + /// Mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Mode { + /// Awaiting initialization + AwaitingInitialization = 0, + + /// Dynamically aligning + DynamicallyAligning = 1, + + /// Ready + Ready = 2, + + /// GNSS Outage exceeds max duration + GnssOutageExceedsMaxDuration = 3, + + /// FastStart seeding + FastStartSeeding = 4, + + /// FastStart validating + FastStartValidating = 5, + + /// Validating unsafe fast start seed + ValidatingUnsafeFastStartSeed = 6, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.flags, buf); + + impl std::fmt::Display for Mode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Mode::AwaitingInitialization => f.write_str("Awaiting initialization"), + Mode::DynamicallyAligning => f.write_str("Dynamically aligning"), + Mode::Ready => f.write_str("Ready"), + Mode::GnssOutageExceedsMaxDuration => { + f.write_str("GNSS Outage exceeds max duration") + } + Mode::FastStartSeeding => f.write_str("FastStart seeding"), + Mode::FastStartValidating => f.write_str("FastStart validating"), + Mode::ValidatingUnsafeFastStartSeed => { + f.write_str("Validating unsafe fast start seed") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgInsStatus { - sender_id: None, - flags: WireFormat::parse_unchecked(buf), + + impl TryFrom for Mode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(Mode::AwaitingInitialization), + 1 => Ok(Mode::DynamicallyAligning), + 2 => Ok(Mode::Ready), + 3 => Ok(Mode::GnssOutageExceedsMaxDuration), + 4 => Ok(Mode::FastStartSeeding), + 5 => Ok(Mode::FastStartValidating), + 6 => Ok(Mode::ValidatingUnsafeFastStartSeed), + i => Err(i), + } } } } -/// Inertial Navigation System update status message -/// -/// The INS update status message contains information about executed and -/// rejected INS updates. This message is expected to be extended in the -/// future as new types of measurements are being added. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgInsUpdates { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// GPS Time of Week - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// GNSS position update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "gnsspos")))] - pub gnsspos: u8, - /// GNSS velocity update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "gnssvel")))] - pub gnssvel: u8, - /// Wheelticks update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "wheelticks")))] - pub wheelticks: u8, - /// Wheelticks update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "speed")))] - pub speed: u8, - /// NHC update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "nhc")))] - pub nhc: u8, - /// Zero velocity update status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "zerovel")))] - pub zerovel: u8, -} +pub mod msg_ins_updates { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Inertial Navigation System update status message + /// + /// The INS update status message contains information about executed and + /// rejected INS updates. This message is expected to be extended in the + /// future as new types of measurements are being added. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgInsUpdates { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// GPS Time of Week + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// GNSS position update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "gnsspos")))] + pub gnsspos: u8, + /// GNSS velocity update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "gnssvel")))] + pub gnssvel: u8, + /// Wheelticks update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "wheelticks")))] + pub wheelticks: u8, + /// Wheelticks update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "speed")))] + pub speed: u8, + /// NHC update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "nhc")))] + pub nhc: u8, + /// Zero velocity update status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "zerovel")))] + pub zerovel: u8, + } + + impl MsgInsUpdates { + /// Gets the `number_of_attempted_gnss_position_updates_since_last_message` stored in `gnsspos`. + pub fn number_of_attempted_gnss_position_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.gnsspos, u8, u8, 7, 4) + } -impl ConcreteMessage for MsgInsUpdates { - const MESSAGE_TYPE: u16 = 65286; - const MESSAGE_NAME: &'static str = "MSG_INS_UPDATES"; -} + /// Sets the `number_of_attempted_gnss_position_updates_since_last_message` bitrange of `gnsspos`. + pub fn set_number_of_attempted_gnss_position_updates_since_last_message( + &mut self, + number_of_attempted_gnss_position_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.gnsspos, + number_of_attempted_gnss_position_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } -impl SbpMessage for MsgInsUpdates { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Gets the `number_of_rejected_gnss_position_updates_since_last_message` stored in `gnsspos`. + pub fn number_of_rejected_gnss_position_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.gnsspos, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_gnss_position_updates_since_last_message` bitrange of `gnsspos`. + pub fn set_number_of_rejected_gnss_position_updates_since_last_message( + &mut self, + number_of_rejected_gnss_position_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.gnsspos, + number_of_rejected_gnss_position_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the `number_of_attempted_gnss_velocity_updates_since_last_message` stored in `gnssvel`. + pub fn number_of_attempted_gnss_velocity_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.gnssvel, u8, u8, 7, 4) + } + + /// Sets the `number_of_attempted_gnss_velocity_updates_since_last_message` bitrange of `gnssvel`. + pub fn set_number_of_attempted_gnss_velocity_updates_since_last_message( + &mut self, + number_of_attempted_gnss_velocity_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.gnssvel, + number_of_attempted_gnss_velocity_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } + + /// Gets the `number_of_rejected_gnss_velocity_updates_since_last_message` stored in `gnssvel`. + pub fn number_of_rejected_gnss_velocity_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.gnssvel, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_gnss_velocity_updates_since_last_message` bitrange of `gnssvel`. + pub fn set_number_of_rejected_gnss_velocity_updates_since_last_message( + &mut self, + number_of_rejected_gnss_velocity_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.gnssvel, + number_of_rejected_gnss_velocity_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the `number_of_attempted_wheeltick_updates_since_last_message` stored in `wheelticks`. + pub fn number_of_attempted_wheeltick_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.wheelticks, u8, u8, 7, 4) + } + + /// Sets the `number_of_attempted_wheeltick_updates_since_last_message` bitrange of `wheelticks`. + pub fn set_number_of_attempted_wheeltick_updates_since_last_message( + &mut self, + number_of_attempted_wheeltick_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.wheelticks, + number_of_attempted_wheeltick_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } + + /// Gets the `number_of_rejected_wheeltick_updates_since_last_message` stored in `wheelticks`. + pub fn number_of_rejected_wheeltick_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.wheelticks, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_wheeltick_updates_since_last_message` bitrange of `wheelticks`. + pub fn set_number_of_rejected_wheeltick_updates_since_last_message( + &mut self, + number_of_rejected_wheeltick_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.wheelticks, + number_of_rejected_wheeltick_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the `number_of_attempted_speed_updates_since_last_message` stored in `speed`. + pub fn number_of_attempted_speed_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.speed, u8, u8, 7, 4) + } + + /// Sets the `number_of_attempted_speed_updates_since_last_message` bitrange of `speed`. + pub fn set_number_of_attempted_speed_updates_since_last_message( + &mut self, + number_of_attempted_speed_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.speed, + number_of_attempted_speed_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } + + /// Gets the `number_of_rejected_speed_updates_since_last_message` stored in `speed`. + pub fn number_of_rejected_speed_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.speed, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_speed_updates_since_last_message` bitrange of `speed`. + pub fn set_number_of_rejected_speed_updates_since_last_message( + &mut self, + number_of_rejected_speed_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.speed, + number_of_rejected_speed_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the `number_of_attempted_nhc_updates_since_last_message` stored in `nhc`. + pub fn number_of_attempted_nhc_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.nhc, u8, u8, 7, 4) + } + + /// Sets the `number_of_attempted_nhc_updates_since_last_message` bitrange of `nhc`. + pub fn set_number_of_attempted_nhc_updates_since_last_message( + &mut self, + number_of_attempted_nhc_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.nhc, + number_of_attempted_nhc_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } + + /// Gets the `number_of_rejected_nhc_updates_since_last_message` stored in `nhc`. + pub fn number_of_rejected_nhc_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.nhc, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_nhc_updates_since_last_message` bitrange of `nhc`. + pub fn set_number_of_rejected_nhc_updates_since_last_message( + &mut self, + number_of_rejected_nhc_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.nhc, + number_of_rejected_nhc_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } + + /// Gets the `number_of_attempted_zero_velocity_updates_since_last_message` stored in `zerovel`. + pub fn number_of_attempted_zero_velocity_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.zerovel, u8, u8, 7, 4) + } + + /// Sets the `number_of_attempted_zero_velocity_updates_since_last_message` bitrange of `zerovel`. + pub fn set_number_of_attempted_zero_velocity_updates_since_last_message( + &mut self, + number_of_attempted_zero_velocity_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.zerovel, + number_of_attempted_zero_velocity_updates_since_last_message, + u8, + u8, + 7, + 4 + ); + } + + /// Gets the `number_of_rejected_zero_velocity_updates_since_last_message` stored in `zerovel`. + pub fn number_of_rejected_zero_velocity_updates_since_last_message(&self) -> u8 { + get_bit_range!(self.zerovel, u8, u8, 3, 0) + } + + /// Sets the `number_of_rejected_zero_velocity_updates_since_last_message` bitrange of `zerovel`. + pub fn set_number_of_rejected_zero_velocity_updates_since_last_message( + &mut self, + number_of_rejected_zero_velocity_updates_since_last_message: u8, + ) { + set_bit_range!( + &mut self.zerovel, + number_of_rejected_zero_velocity_updates_since_last_message, + u8, + u8, + 3, + 0 + ); + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl ConcreteMessage for MsgInsUpdates { + const MESSAGE_TYPE: u16 = 65286; + const MESSAGE_NAME: &'static str = "MSG_INS_UPDATES"; } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl SbpMessage for MsgInsUpdates { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl TryFrom for MsgInsUpdates { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgInsUpdates(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } -} -impl TryFrom for MsgInsUpdates { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgInsUpdates(m) => Ok(m), - _ => Err(TryFromSbpError), + impl WireFormat for MsgInsUpdates { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.gnsspos) + + WireFormat::len(&self.gnssvel) + + WireFormat::len(&self.wheelticks) + + WireFormat::len(&self.speed) + + WireFormat::len(&self.nhc) + + WireFormat::len(&self.zerovel) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.gnsspos, buf); + WireFormat::write(&self.gnssvel, buf); + WireFormat::write(&self.wheelticks, buf); + WireFormat::write(&self.speed, buf); + WireFormat::write(&self.nhc, buf); + WireFormat::write(&self.zerovel, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgInsUpdates { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + gnsspos: WireFormat::parse_unchecked(buf), + gnssvel: WireFormat::parse_unchecked(buf), + wheelticks: WireFormat::parse_unchecked(buf), + speed: WireFormat::parse_unchecked(buf), + nhc: WireFormat::parse_unchecked(buf), + zerovel: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgInsUpdates { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) - + WireFormat::len(&self.gnsspos) - + WireFormat::len(&self.gnssvel) - + WireFormat::len(&self.wheelticks) - + WireFormat::len(&self.speed) - + WireFormat::len(&self.nhc) - + WireFormat::len(&self.zerovel) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.gnsspos, buf); - WireFormat::write(&self.gnssvel, buf); - WireFormat::write(&self.wheelticks, buf); - WireFormat::write(&self.speed, buf); - WireFormat::write(&self.nhc, buf); - WireFormat::write(&self.zerovel, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgInsUpdates { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - gnsspos: WireFormat::parse_unchecked(buf), - gnssvel: WireFormat::parse_unchecked(buf), - wheelticks: WireFormat::parse_unchecked(buf), - speed: WireFormat::parse_unchecked(buf), - nhc: WireFormat::parse_unchecked(buf), - zerovel: WireFormat::parse_unchecked(buf), +pub mod msg_pps_time { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Local time at detection of PPS pulse + /// + /// The PPS time message contains the value of the sender's local time in + /// microseconds at the moment a pulse is detected on the PPS input. This is + /// to be used for syncronisation of sensor data sampled with a local + /// timestamp (e.g. IMU or wheeltick messages) where GNSS time is unknown to + /// the sender. + /// + /// The local time used to timestamp the PPS pulse must be generated by the + /// same clock which is used to timestamp the IMU/wheel sensor data and should + /// follow the same roll-over rules. A separate MSG_PPS_TIME message should + /// be sent for each source of sensor data which uses PPS-relative + /// timestamping. The sender ID for each of these MSG_PPS_TIME messages + /// should match the sender ID of the respective sensor data. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgPpsTime { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Local time in microseconds + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u64, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + } + + impl MsgPpsTime { + /// Gets the `reserved_set_to_zero` stored in `flags`. + pub fn reserved_set_to_zero(&self) -> u8 { + get_bit_range!(self.flags, u8, u8, 7, 2) + } + + /// Sets the `reserved_set_to_zero` bitrange of `flags`. + pub fn set_reserved_set_to_zero(&mut self, reserved_set_to_zero: u8) { + set_bit_range!(&mut self.flags, reserved_set_to_zero, u8, u8, 7, 2); + } + + /// Gets the [TimeUncertainty][self::TimeUncertainty] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeUncertainty` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeUncertainty` were added. + pub fn time_uncertainty(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeUncertainty][TimeUncertainty] of the `flags` bitfield. + pub fn set_time_uncertainty(&mut self, time_uncertainty: TimeUncertainty) { + set_bit_range!(&mut self.flags, time_uncertainty, u8, u8, 1, 0); } } -} -/// Local time at detection of PPS pulse -/// -/// The PPS time message contains the value of the sender's local time in -/// microseconds at the moment a pulse is detected on the PPS input. This is -/// to be used for syncronisation of sensor data sampled with a local -/// timestamp (e.g. IMU or wheeltick messages) where GNSS time is unknown to -/// the sender. -/// -/// The local time used to timestamp the PPS pulse must be generated by the -/// same clock which is used to timestamp the IMU/wheel sensor data and should -/// follow the same roll-over rules. A separate MSG_PPS_TIME message should -/// be sent for each source of sensor data which uses PPS-relative -/// timestamping. The sender ID for each of these MSG_PPS_TIME messages -/// should match the sender ID of the respective sensor data. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgPpsTime { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Local time in microseconds - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u64, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} + impl ConcreteMessage for MsgPpsTime { + const MESSAGE_TYPE: u16 = 65288; + const MESSAGE_NAME: &'static str = "MSG_PPS_TIME"; + } -impl ConcreteMessage for MsgPpsTime { - const MESSAGE_TYPE: u16 = 65288; - const MESSAGE_NAME: &'static str = "MSG_PPS_TIME"; -} + impl SbpMessage for MsgPpsTime { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } -impl SbpMessage for MsgPpsTime { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl TryFrom for MsgPpsTime { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgPpsTime(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl WireFormat for MsgPpsTime { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgPpsTime { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// Time uncertainty + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeUncertainty { + /// Unknown + Unknown = 0, + + /// +/- 10 milliseconds + _10Milliseconds = 1, + + /// +/- 10 microseconds + _10Microseconds = 2, + + /// < 1 microseconds + _1Microseconds = 3, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TimeUncertainty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeUncertainty::Unknown => f.write_str("Unknown"), + TimeUncertainty::_10Milliseconds => f.write_str("+/- 10 milliseconds"), + TimeUncertainty::_10Microseconds => f.write_str("+/- 10 microseconds"), + TimeUncertainty::_1Microseconds => f.write_str("< 1 microseconds"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TimeUncertainty { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeUncertainty::Unknown), + 1 => Ok(TimeUncertainty::_10Milliseconds), + 2 => Ok(TimeUncertainty::_10Microseconds), + 3 => Ok(TimeUncertainty::_1Microseconds), + i => Err(i), + } + } } } -impl TryFrom for MsgPpsTime { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgPpsTime(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod msg_sensor_aid_event { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Sensor state and update status data + /// + /// This diagnostic message contains state and update status information for + /// all sensors that are being used by the fusion engine. This message will be + /// generated asynchronously to the solution messages and will be emitted + /// anytime a sensor update is being processed. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgSensorAidEvent { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Update timestamp in milliseconds. + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u32, + /// Sensor type + #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_type")))] + pub sensor_type: u8, + /// Sensor identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_id")))] + pub sensor_id: u16, + /// Reserved for future use + #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_state")))] + pub sensor_state: u8, + /// Number of available measurements in this epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_available_meas")))] + pub n_available_meas: u8, + /// Number of attempted measurements in this epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_attempted_meas")))] + pub n_attempted_meas: u8, + /// Number of accepted measurements in this epoch + #[cfg_attr(feature = "serde", serde(rename(serialize = "n_accepted_meas")))] + pub n_accepted_meas: u8, + /// Reserved for future use + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u32, + } + + impl MsgSensorAidEvent { + /// Gets the [TypeIdentifier][self::TypeIdentifier] stored in the `sensor_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TypeIdentifier` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TypeIdentifier` were added. + pub fn type_identifier(&self) -> Result { + get_bit_range!(self.sensor_type, u8, u8, 7, 0).try_into() + } + + /// Set the bitrange corresponding to the [TypeIdentifier][TypeIdentifier] of the `sensor_type` bitfield. + pub fn set_type_identifier(&mut self, type_identifier: TypeIdentifier) { + set_bit_range!(&mut self.sensor_type, type_identifier, u8, u8, 7, 0); } } -} -impl WireFormat for MsgPpsTime { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) + WireFormat::len(&self.flags) + impl ConcreteMessage for MsgSensorAidEvent { + const MESSAGE_TYPE: u16 = 65289; + const MESSAGE_NAME: &'static str = "MSG_SENSOR_AID_EVENT"; + } + + impl SbpMessage for MsgSensorAidEvent { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.flags, buf); + + impl TryFrom for MsgSensorAidEvent { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgSensorAidEvent(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgPpsTime { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgSensorAidEvent { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.sensor_type) + + WireFormat::len(&self.sensor_id) + + WireFormat::len(&self.sensor_state) + + WireFormat::len(&self.n_available_meas) + + WireFormat::len(&self.n_attempted_meas) + + WireFormat::len(&self.n_accepted_meas) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.sensor_type, buf); + WireFormat::write(&self.sensor_id, buf); + WireFormat::write(&self.sensor_state, buf); + WireFormat::write(&self.n_available_meas, buf); + WireFormat::write(&self.n_attempted_meas, buf); + WireFormat::write(&self.n_accepted_meas, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgSensorAidEvent { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + sensor_type: WireFormat::parse_unchecked(buf), + sensor_id: WireFormat::parse_unchecked(buf), + sensor_state: WireFormat::parse_unchecked(buf), + n_available_meas: WireFormat::parse_unchecked(buf), + n_attempted_meas: WireFormat::parse_unchecked(buf), + n_accepted_meas: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } } } -} -/// Sensor state and update status data -/// -/// This diagnostic message contains state and update status information for -/// all sensors that are being used by the fusion engine. This message will be -/// generated asynchronously to the solution messages and will be emitted -/// anytime a sensor update is being processed. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgSensorAidEvent { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Update timestamp in milliseconds. - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u32, - /// Sensor type - #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_type")))] - pub sensor_type: u8, - /// Sensor identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_id")))] - pub sensor_id: u16, - /// Reserved for future use - #[cfg_attr(feature = "serde", serde(rename(serialize = "sensor_state")))] - pub sensor_state: u8, - /// Number of available measurements in this epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_available_meas")))] - pub n_available_meas: u8, - /// Number of attempted measurements in this epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_attempted_meas")))] - pub n_attempted_meas: u8, - /// Number of accepted measurements in this epoch - #[cfg_attr(feature = "serde", serde(rename(serialize = "n_accepted_meas")))] - pub n_accepted_meas: u8, - /// Reserved for future use - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u32, -} + /// Type identifier + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TypeIdentifier { + /// GNSS position + GnssPosition = 0, -impl ConcreteMessage for MsgSensorAidEvent { - const MESSAGE_TYPE: u16 = 65289; - const MESSAGE_NAME: &'static str = "MSG_SENSOR_AID_EVENT"; -} + /// GNSS average velocity + GnssAverageVelocity = 1, -impl SbpMessage for MsgSensorAidEvent { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// GNSS instantaneous velocity + GnssInstantaneousVelocity = 2, + + /// Wheel ticks + WheelTicks = 3, + + /// Wheel speed + WheelSpeed = 4, + + /// IMU + Imu = 5, + + /// Time differences of carrier phase + TimeDifferencesOfCarrierPhase = 6, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for TypeIdentifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TypeIdentifier::GnssPosition => f.write_str("GNSS position"), + TypeIdentifier::GnssAverageVelocity => f.write_str("GNSS average velocity"), + TypeIdentifier::GnssInstantaneousVelocity => { + f.write_str("GNSS instantaneous velocity") + } + TypeIdentifier::WheelTicks => f.write_str("Wheel ticks"), + TypeIdentifier::WheelSpeed => f.write_str("Wheel speed"), + TypeIdentifier::Imu => f.write_str("IMU"), + TypeIdentifier::TimeDifferencesOfCarrierPhase => { + f.write_str("Time differences of carrier phase") + } + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for TypeIdentifier { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TypeIdentifier::GnssPosition), + 1 => Ok(TypeIdentifier::GnssAverageVelocity), + 2 => Ok(TypeIdentifier::GnssInstantaneousVelocity), + 3 => Ok(TypeIdentifier::WheelTicks), + 4 => Ok(TypeIdentifier::WheelSpeed), + 5 => Ok(TypeIdentifier::Imu), + 6 => Ok(TypeIdentifier::TimeDifferencesOfCarrierPhase), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +} + +pub mod msg_startup { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// System start-up message + /// + /// The system start-up message is sent once on system start-up. It notifies + /// the host or other attached devices that the system has started and is now + /// ready to respond to commands or configuration requests. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStartup { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Cause of startup + #[cfg_attr(feature = "serde", serde(rename(serialize = "cause")))] + pub cause: u8, + /// Startup type + #[cfg_attr(feature = "serde", serde(rename(serialize = "startup_type")))] + pub startup_type: u8, + /// Reserved + #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] + pub reserved: u16, + } + + impl MsgStartup { + /// Gets the [CauseOfStartup][self::CauseOfStartup] stored in the `cause` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CauseOfStartup` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CauseOfStartup` were added. + pub fn cause_of_startup(&self) -> Result { + get_bit_range!(self.cause, u8, u8, 8, 0).try_into() + } + + /// Set the bitrange corresponding to the [CauseOfStartup][CauseOfStartup] of the `cause` bitfield. + pub fn set_cause_of_startup(&mut self, cause_of_startup: CauseOfStartup) { + set_bit_range!(&mut self.cause, cause_of_startup, u8, u8, 8, 0); + } + + /// Gets the [StartupType][self::StartupType] stored in the `startup_type` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `StartupType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `StartupType` were added. + pub fn startup_type(&self) -> Result { + get_bit_range!(self.startup_type, u8, u8, 8, 0).try_into() + } + + /// Set the bitrange corresponding to the [StartupType][StartupType] of the `startup_type` bitfield. + pub fn set_startup_type(&mut self, startup_type: StartupType) { + set_bit_range!(&mut self.startup_type, startup_type, u8, u8, 8, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgStartup { + const MESSAGE_TYPE: u16 = 65280; + const MESSAGE_NAME: &'static str = "MSG_STARTUP"; } -} -impl TryFrom for MsgSensorAidEvent { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgSensorAidEvent(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgStartup { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgSensorAidEvent { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.sensor_type) - + WireFormat::len(&self.sensor_id) - + WireFormat::len(&self.sensor_state) - + WireFormat::len(&self.n_available_meas) - + WireFormat::len(&self.n_attempted_meas) - + WireFormat::len(&self.n_accepted_meas) - + WireFormat::len(&self.flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.sensor_type, buf); - WireFormat::write(&self.sensor_id, buf); - WireFormat::write(&self.sensor_state, buf); - WireFormat::write(&self.n_available_meas, buf); - WireFormat::write(&self.n_attempted_meas, buf); - WireFormat::write(&self.n_accepted_meas, buf); - WireFormat::write(&self.flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgSensorAidEvent { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - sensor_type: WireFormat::parse_unchecked(buf), - sensor_id: WireFormat::parse_unchecked(buf), - sensor_state: WireFormat::parse_unchecked(buf), - n_available_meas: WireFormat::parse_unchecked(buf), - n_attempted_meas: WireFormat::parse_unchecked(buf), - n_accepted_meas: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + impl TryFrom for MsgStartup { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStartup(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgStartup { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.cause) + + WireFormat::len(&self.startup_type) + + WireFormat::len(&self.reserved) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.cause, buf); + WireFormat::write(&self.startup_type, buf); + WireFormat::write(&self.reserved, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgStartup { + sender_id: None, + cause: WireFormat::parse_unchecked(buf), + startup_type: WireFormat::parse_unchecked(buf), + reserved: WireFormat::parse_unchecked(buf), + } } } -} -/// System start-up message -/// -/// The system start-up message is sent once on system start-up. It notifies -/// the host or other attached devices that the system has started and is now -/// ready to respond to commands or configuration requests. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStartup { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, /// Cause of startup - #[cfg_attr(feature = "serde", serde(rename(serialize = "cause")))] - pub cause: u8, - /// Startup type - #[cfg_attr(feature = "serde", serde(rename(serialize = "startup_type")))] - pub startup_type: u8, - /// Reserved - #[cfg_attr(feature = "serde", serde(rename(serialize = "reserved")))] - pub reserved: u16, -} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CauseOfStartup { + /// Power on + PowerOn = 0, -impl ConcreteMessage for MsgStartup { - const MESSAGE_TYPE: u16 = 65280; - const MESSAGE_NAME: &'static str = "MSG_STARTUP"; -} + /// Software reset + SoftwareReset = 1, -impl SbpMessage for MsgStartup { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Watchdog reset + WatchdogReset = 2, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for CauseOfStartup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CauseOfStartup::PowerOn => f.write_str("Power on"), + CauseOfStartup::SoftwareReset => f.write_str("Software reset"), + CauseOfStartup::WatchdogReset => f.write_str("Watchdog reset"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for CauseOfStartup { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CauseOfStartup::PowerOn), + 1 => Ok(CauseOfStartup::SoftwareReset), + 2 => Ok(CauseOfStartup::WatchdogReset), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum StartupType { + /// Cold start + ColdStart = 0, + + /// Warm start + WarmStart = 1, + + /// Hot start + HotStart = 2, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for StartupType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StartupType::ColdStart => f.write_str("Cold start"), + StartupType::WarmStart => f.write_str("Warm start"), + StartupType::HotStart => f.write_str("Hot start"), + } + } } -} -impl TryFrom for MsgStartup { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStartup(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for StartupType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(StartupType::ColdStart), + 1 => Ok(StartupType::WarmStart), + 2 => Ok(StartupType::HotStart), + i => Err(i), + } } } } -impl WireFormat for MsgStartup { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.cause) - + WireFormat::len(&self.startup_type) - + WireFormat::len(&self.reserved) +pub mod msg_status_report { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Status report message + /// + /// The status report is sent periodically to inform the host or other + /// attached devices that the system is running. It is used to monitor system + /// malfunctions. It contains status reports that indicate to the host the + /// status of each sub-system and whether it is operating correctly. + /// + /// Interpretation of the subsystem specific status code is product dependent, + /// but if the generic status code is initializing, it should be ignored. + /// Refer to product documentation for details. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgStatusReport { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Identity of reporting system + #[cfg_attr(feature = "serde", serde(rename(serialize = "reporting_system")))] + pub reporting_system: u16, + /// SBP protocol version + #[cfg_attr(feature = "serde", serde(rename(serialize = "sbp_version")))] + pub sbp_version: u16, + /// Increments on each status report sent + #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] + pub sequence: u32, + /// Number of seconds since system start-up + #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] + pub uptime: u32, + /// Reported status of individual subsystems + #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] + pub status: Vec, + } + + impl MsgStatusReport { + /// Gets the [System][self::System] stored in the `reporting_system` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `System` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u16)`. This may be because of a malformed message, + /// or because new variants of `System` were added. + pub fn system(&self) -> Result { + get_bit_range!(self.reporting_system, u16, u16, 15, 0).try_into() + } + + /// Set the bitrange corresponding to the [System][System] of the `reporting_system` bitfield. + pub fn set_system(&mut self, system: System) { + set_bit_range!(&mut self.reporting_system, system, u16, u16, 15, 0); + } + + /// Gets the `sbp_major_protocol_version_number` stored in `sbp_version`. + pub fn sbp_major_protocol_version_number(&self) -> u8 { + get_bit_range!(self.sbp_version, u16, u8, 15, 8) + } + + /// Sets the `sbp_major_protocol_version_number` bitrange of `sbp_version`. + pub fn set_sbp_major_protocol_version_number( + &mut self, + sbp_major_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.sbp_version, + sbp_major_protocol_version_number, + u16, + u8, + 15, + 8 + ); + } + + /// Gets the `sbp_minor_protocol_version_number` stored in `sbp_version`. + pub fn sbp_minor_protocol_version_number(&self) -> u8 { + get_bit_range!(self.sbp_version, u16, u8, 7, 0) + } + + /// Sets the `sbp_minor_protocol_version_number` bitrange of `sbp_version`. + pub fn set_sbp_minor_protocol_version_number( + &mut self, + sbp_minor_protocol_version_number: u8, + ) { + set_bit_range!( + &mut self.sbp_version, + sbp_minor_protocol_version_number, + u16, + u8, + 7, + 0 + ); + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.cause, buf); - WireFormat::write(&self.startup_type, buf); - WireFormat::write(&self.reserved, buf); + + impl ConcreteMessage for MsgStatusReport { + const MESSAGE_TYPE: u16 = 65534; + const MESSAGE_NAME: &'static str = "MSG_STATUS_REPORT"; } - fn parse_unchecked(buf: &mut B) -> Self { - MsgStartup { - sender_id: None, - cause: WireFormat::parse_unchecked(buf), - startup_type: WireFormat::parse_unchecked(buf), - reserved: WireFormat::parse_unchecked(buf), + + impl SbpMessage for MsgStatusReport { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -/// Status report message -/// -/// The status report is sent periodically to inform the host or other -/// attached devices that the system is running. It is used to monitor system -/// malfunctions. It contains status reports that indicate to the host the -/// status of each sub-system and whether it is operating correctly. -/// -/// Interpretation of the subsystem specific status code is product dependent, -/// but if the generic status code is initializing, it should be ignored. -/// Refer to product documentation for details. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgStatusReport { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Identity of reporting system - #[cfg_attr(feature = "serde", serde(rename(serialize = "reporting_system")))] - pub reporting_system: u16, - /// SBP protocol version - #[cfg_attr(feature = "serde", serde(rename(serialize = "sbp_version")))] - pub sbp_version: u16, - /// Increments on each status report sent - #[cfg_attr(feature = "serde", serde(rename(serialize = "sequence")))] - pub sequence: u32, - /// Number of seconds since system start-up - #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] - pub uptime: u32, - /// Reported status of individual subsystems - #[cfg_attr(feature = "serde", serde(rename(serialize = "status")))] - pub status: Vec, -} + impl TryFrom for MsgStatusReport { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgStatusReport(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } -impl ConcreteMessage for MsgStatusReport { - const MESSAGE_TYPE: u16 = 65534; - const MESSAGE_NAME: &'static str = "MSG_STATUS_REPORT"; -} + impl WireFormat for MsgStatusReport { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.reporting_system) + + WireFormat::len(&self.sbp_version) + + WireFormat::len(&self.sequence) + + WireFormat::len(&self.uptime) + + WireFormat::len(&self.status) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.reporting_system, buf); + WireFormat::write(&self.sbp_version, buf); + WireFormat::write(&self.sequence, buf); + WireFormat::write(&self.uptime, buf); + WireFormat::write(&self.status, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgStatusReport { + sender_id: None, + reporting_system: WireFormat::parse_unchecked(buf), + sbp_version: WireFormat::parse_unchecked(buf), + sequence: WireFormat::parse_unchecked(buf), + uptime: WireFormat::parse_unchecked(buf), + status: WireFormat::parse_unchecked(buf), + } + } + } -impl SbpMessage for MsgStatusReport { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// System + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum System { + /// Starling + Starling = 0, + + /// Precision GNSS Module (PGM) + PrecisionGnssModule = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for System { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + System::Starling => f.write_str("Starling"), + System::PrecisionGnssModule => f.write_str("Precision GNSS Module (PGM)"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for System { + type Error = u16; + fn try_from(i: u16) -> Result { + match i { + 0 => Ok(System::Starling), + 1 => Ok(System::PrecisionGnssModule), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); +} + +pub mod sub_system_report { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Sub-system Status report + /// + /// Report the general and specific state of a sub-system. If the generic + /// state is reported as initializing, the specific state should be ignored. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct SubSystemReport { + /// Identity of reporting subsystem + #[cfg_attr(feature = "serde", serde(rename(serialize = "component")))] + pub component: u16, + /// Generic form status report + #[cfg_attr(feature = "serde", serde(rename(serialize = "generic")))] + pub generic: u8, + /// Subsystem specific status code + #[cfg_attr(feature = "serde", serde(rename(serialize = "specific")))] + pub specific: u8, + } + + impl SubSystemReport { + /// Gets the [Subsystem][self::Subsystem] stored in the `component` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Subsystem` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u16)`. This may be because of a malformed message, + /// or because new variants of `Subsystem` were added. + pub fn subsystem(&self) -> Result { + get_bit_range!(self.component, u16, u16, 15, 0).try_into() + } + + /// Set the bitrange corresponding to the [Subsystem][Subsystem] of the `component` bitfield. + pub fn set_subsystem(&mut self, subsystem: Subsystem) { + set_bit_range!(&mut self.component, subsystem, u16, u16, 15, 0); + } + + /// Gets the [Generic][self::Generic] stored in the `generic` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `Generic` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `Generic` were added. + pub fn generic(&self) -> Result { + get_bit_range!(self.generic, u8, u8, 7, 0).try_into() + } + + /// Set the bitrange corresponding to the [Generic][Generic] of the `generic` bitfield. + pub fn set_generic(&mut self, generic: Generic) { + set_bit_range!(&mut self.generic, generic, u8, u8, 7, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl WireFormat for SubSystemReport { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.component) + + WireFormat::len(&self.generic) + + WireFormat::len(&self.specific) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.component, buf); + WireFormat::write(&self.generic, buf); + WireFormat::write(&self.specific, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + SubSystemReport { + component: WireFormat::parse_unchecked(buf), + generic: WireFormat::parse_unchecked(buf), + specific: WireFormat::parse_unchecked(buf), + } + } } -} -impl TryFrom for MsgStatusReport { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgStatusReport(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Subsystem + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Subsystem { + /// Primary GNSS Antenna + PrimaryGnssAntenna = 0, + + /// Measurement Engine + MeasurementEngine = 1, + + /// Corrections Client + CorrectionsClient = 2, + + /// Differential GNSS Engine + DifferentialGnssEngine = 3, + + /// CAN + CAN = 4, + + /// Wheel Odometry + WheelOdometry = 5, + + /// Sensor Fusion Engine + SensorFusionEngine = 6, + } + + impl std::fmt::Display for Subsystem { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Subsystem::PrimaryGnssAntenna => f.write_str("Primary GNSS Antenna"), + Subsystem::MeasurementEngine => f.write_str("Measurement Engine"), + Subsystem::CorrectionsClient => f.write_str("Corrections Client"), + Subsystem::DifferentialGnssEngine => f.write_str("Differential GNSS Engine"), + Subsystem::CAN => f.write_str("CAN"), + Subsystem::WheelOdometry => f.write_str("Wheel Odometry"), + Subsystem::SensorFusionEngine => f.write_str("Sensor Fusion Engine"), + } } } -} -impl WireFormat for MsgStatusReport { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.reporting_system) - + WireFormat::len(&self.sbp_version) - + WireFormat::len(&self.sequence) - + WireFormat::len(&self.uptime) - + WireFormat::len(&self.status) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.reporting_system, buf); - WireFormat::write(&self.sbp_version, buf); - WireFormat::write(&self.sequence, buf); - WireFormat::write(&self.uptime, buf); - WireFormat::write(&self.status, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgStatusReport { - sender_id: None, - reporting_system: WireFormat::parse_unchecked(buf), - sbp_version: WireFormat::parse_unchecked(buf), - sequence: WireFormat::parse_unchecked(buf), - uptime: WireFormat::parse_unchecked(buf), - status: WireFormat::parse_unchecked(buf), + impl TryFrom for Subsystem { + type Error = u16; + fn try_from(i: u16) -> Result { + match i { + 0 => Ok(Subsystem::PrimaryGnssAntenna), + 1 => Ok(Subsystem::MeasurementEngine), + 2 => Ok(Subsystem::CorrectionsClient), + 3 => Ok(Subsystem::DifferentialGnssEngine), + 4 => Ok(Subsystem::CAN), + 5 => Ok(Subsystem::WheelOdometry), + 6 => Ok(Subsystem::SensorFusionEngine), + i => Err(i), + } } } -} -/// Sub-system Status report -/// -/// Report the general and specific state of a sub-system. If the generic -/// state is reported as initializing, the specific state should be ignored. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct SubSystemReport { - /// Identity of reporting subsystem - #[cfg_attr(feature = "serde", serde(rename(serialize = "component")))] - pub component: u16, - /// Generic form status report - #[cfg_attr(feature = "serde", serde(rename(serialize = "generic")))] - pub generic: u8, - /// Subsystem specific status code - #[cfg_attr(feature = "serde", serde(rename(serialize = "specific")))] - pub specific: u8, -} + /// Generic + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum Generic { + /// OK/Nominal + OKNominal = 0, + + /// Initializing + Initializing = 1, + + /// Unknown + Unknown = 2, + + /// Degraded + Degraded = 3, + + /// Unusable + Unusable = 4, + } + + impl std::fmt::Display for Generic { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Generic::OKNominal => f.write_str("OK/Nominal"), + Generic::Initializing => f.write_str("Initializing"), + Generic::Unknown => f.write_str("Unknown"), + Generic::Degraded => f.write_str("Degraded"), + Generic::Unusable => f.write_str("Unusable"), + } + } + } -impl WireFormat for SubSystemReport { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.component) - + WireFormat::len(&self.generic) - + WireFormat::len(&self.specific) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.component, buf); - WireFormat::write(&self.generic, buf); - WireFormat::write(&self.specific, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - SubSystemReport { - component: WireFormat::parse_unchecked(buf), - generic: WireFormat::parse_unchecked(buf), - specific: WireFormat::parse_unchecked(buf), + impl TryFrom for Generic { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(Generic::OKNominal), + 1 => Ok(Generic::Initializing), + 2 => Ok(Generic::Unknown), + 3 => Ok(Generic::Degraded), + 4 => Ok(Generic::Unusable), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/tracking.rs b/rust/sbp/src/messages/tracking.rs index 6f101e84af..fc242a5700 100644 --- a/rust/sbp/src/messages/tracking.rs +++ b/rust/sbp/src/messages/tracking.rs @@ -13,1135 +13,2961 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Satellite code and carrier-phase tracking messages from the device. +pub use measurement_state::MeasurementState; +pub use msg_measurement_state::MsgMeasurementState; +pub use msg_tracking_iq::MsgTrackingIq; +pub use msg_tracking_iq_dep_a::MsgTrackingIqDepA; +pub use msg_tracking_iq_dep_b::MsgTrackingIqDepB; +pub use msg_tracking_state::MsgTrackingState; +pub use msg_tracking_state_dep_a::MsgTrackingStateDepA; +pub use msg_tracking_state_dep_b::MsgTrackingStateDepB; +pub use msg_tracking_state_detailed_dep::MsgTrackingStateDetailedDep; +pub use msg_tracking_state_detailed_dep_a::MsgTrackingStateDetailedDepA; +pub use tracking_channel_correlation::TrackingChannelCorrelation; +pub use tracking_channel_correlation_dep::TrackingChannelCorrelationDep; +pub use tracking_channel_state::TrackingChannelState; +pub use tracking_channel_state_dep_a::TrackingChannelStateDepA; +pub use tracking_channel_state_dep_b::TrackingChannelStateDepB; -use super::gnss::*; - -use super::lib::*; - -/// Measurement Engine signal tracking channel states -/// -/// The tracking message returns a variable-length array of tracking channel -/// states. It reports status and carrier-to-noise density measurements for -/// all tracked satellites. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgMeasurementState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// ME signal tracking channel state - #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] - pub states: Vec, +pub mod msg_measurement_state { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Measurement Engine signal tracking channel states + /// + /// The tracking message returns a variable-length array of tracking channel + /// states. It reports status and carrier-to-noise density measurements for + /// all tracked satellites. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgMeasurementState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// ME signal tracking channel state + #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] + pub states: Vec, + } + + impl ConcreteMessage for MsgMeasurementState { + const MESSAGE_TYPE: u16 = 97; + const MESSAGE_NAME: &'static str = "MSG_MEASUREMENT_STATE"; + } + + impl SbpMessage for MsgMeasurementState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgMeasurementState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgMeasurementState(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgMeasurementState { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.states) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.states, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgMeasurementState { + sender_id: None, + states: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_tracking_iq { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Tracking channel correlations + /// + /// When enabled, a tracking channel can output the correlations at each + /// update interval. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingIq { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Tracking channel of origin + #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] + pub channel: u8, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Early, Prompt and Late correlations + #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] + pub corrs: [TrackingChannelCorrelation; 3], + } + + impl ConcreteMessage for MsgTrackingIq { + const MESSAGE_TYPE: u16 = 45; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ"; + } + + impl SbpMessage for MsgTrackingIq { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingIq { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingIq(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingIq { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + <[TrackingChannelCorrelation; 3] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.channel) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.corrs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.channel, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.corrs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingIq { + sender_id: None, + channel: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + corrs: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_tracking_iq_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingIqDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Tracking channel of origin + #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] + pub channel: u8, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Early, Prompt and Late correlations + #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] + pub corrs: [TrackingChannelCorrelationDep; 3], + } + + impl ConcreteMessage for MsgTrackingIqDepA { + const MESSAGE_TYPE: u16 = 28; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ_DEP_A"; + } + + impl SbpMessage for MsgTrackingIqDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingIqDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingIqDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingIqDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + <[TrackingChannelCorrelationDep; 3] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.channel) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.corrs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.channel, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.corrs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingIqDepA { + sender_id: None, + channel: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + corrs: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_tracking_iq_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Tracking channel correlations + /// + /// When enabled, a tracking channel can output the correlations at each + /// update interval. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingIqDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Tracking channel of origin + #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] + pub channel: u8, + /// GNSS signal identifier + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Early, Prompt and Late correlations + #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] + pub corrs: [TrackingChannelCorrelationDep; 3], + } + + impl ConcreteMessage for MsgTrackingIqDepB { + const MESSAGE_TYPE: u16 = 44; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ_DEP_B"; + } + + impl SbpMessage for MsgTrackingIqDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingIqDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingIqDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingIqDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + <[TrackingChannelCorrelationDep; 3] as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.channel) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.corrs) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.channel, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.corrs, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingIqDepB { + sender_id: None, + channel: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + corrs: WireFormat::parse_unchecked(buf), + } + } + } } -impl ConcreteMessage for MsgMeasurementState { - const MESSAGE_TYPE: u16 = 97; - const MESSAGE_NAME: &'static str = "MSG_MEASUREMENT_STATE"; +pub mod msg_tracking_state { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Signal tracking channel states + /// + /// The tracking message returns a variable-length array of tracking channel + /// states. It reports status and carrier-to-noise density measurements for + /// all tracked satellites. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingState { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Signal tracking channel state + #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] + pub states: Vec, + } + + impl ConcreteMessage for MsgTrackingState { + const MESSAGE_TYPE: u16 = 65; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE"; + } + + impl SbpMessage for MsgTrackingState { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingState { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingState(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingState { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.states) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.states, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingState { + sender_id: None, + states: WireFormat::parse_unchecked(buf), + } + } + } } -impl SbpMessage for MsgMeasurementState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_tracking_state_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingStateDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Satellite tracking channel state + #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] + pub states: Vec, + } + + impl ConcreteMessage for MsgTrackingStateDepA { + const MESSAGE_TYPE: u16 = 22; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DEP_A"; + } + + impl SbpMessage for MsgTrackingStateDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingStateDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingStateDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingStateDepA { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.states) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.states, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingStateDepA { + sender_id: None, + states: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_tracking_state_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingStateDepB { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Signal tracking channel state + #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] + pub states: Vec, + } + + impl ConcreteMessage for MsgTrackingStateDepB { + const MESSAGE_TYPE: u16 = 19; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DEP_B"; + } + + impl SbpMessage for MsgTrackingStateDepB { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingStateDepB { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingStateDepB(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingStateDepB { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.states) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.states, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingStateDepB { + sender_id: None, + states: WireFormat::parse_unchecked(buf), + } + } + } +} + +pub mod msg_tracking_state_detailed_dep { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingStateDetailedDep { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Receiver clock time. + #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] + pub recv_time: u64, + /// Time of transmission of signal from satellite. TOW only valid when TOW + /// status is decoded or propagated. WN only valid when week number valid + /// flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tot")))] + pub tot: GpsTimeDep, + /// Pseudorange observation. Valid only when pseudorange valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Pseudorange observation standard deviation. Valid only when pseudorange + /// valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "P_std")))] + pub p_std: u16, + /// Carrier phase observation with typical sign convention. Valid only when + /// PLL pessimistic lock is achieved. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhase, + /// Carrier-to-Noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock time. It is encoded according to DF402 from the RTCM 10403.2 + /// Amendment 2 specification. Valid values range from 0 to 15. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u16, + /// GNSS signal identifier. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Carrier Doppler frequency. + #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler")))] + pub doppler: i32, + /// Carrier Doppler frequency standard deviation. + #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler_std")))] + pub doppler_std: u16, + /// Number of seconds of continuous tracking. Specifies how much time signal + /// is in continuous track. + #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] + pub uptime: u32, + /// TCXO clock offset. Valid only when valid clock valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_offset")))] + pub clock_offset: i16, + /// TCXO clock drift. Valid only when valid clock valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_drift")))] + pub clock_drift: i16, + /// Early-Prompt (EP) and Prompt-Late (PL) correlators spacing. + #[cfg_attr(feature = "serde", serde(rename(serialize = "corr_spacing")))] + pub corr_spacing: u16, + /// Acceleration. Valid only when acceleration valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "acceleration")))] + pub acceleration: i8, + /// Synchronization status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sync_flags")))] + pub sync_flags: u8, + /// TOW status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_flags")))] + pub tow_flags: u8, + /// Tracking loop status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "track_flags")))] + pub track_flags: u8, + /// Navigation data status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "nav_flags")))] + pub nav_flags: u8, + /// Parameters sets flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "pset_flags")))] + pub pset_flags: u8, + /// Miscellaneous flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "misc_flags")))] + pub misc_flags: u8, + } + + impl MsgTrackingStateDetailedDep { + /// Gets the [SynchronizationStatus][self::SynchronizationStatus] stored in the `sync_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SynchronizationStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SynchronizationStatus` were added. + pub fn synchronization_status(&self) -> Result { + get_bit_range!(self.sync_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [SynchronizationStatus][SynchronizationStatus] of the `sync_flags` bitfield. + pub fn set_synchronization_status( + &mut self, + synchronization_status: SynchronizationStatus, + ) { + set_bit_range!(&mut self.sync_flags, synchronization_status, u8, u8, 2, 0); + } + + /// Gets the [WeekNumberValidityStatus][self::WeekNumberValidityStatus] stored in the `tow_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `WeekNumberValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `WeekNumberValidityStatus` were added. + pub fn week_number_validity_status(&self) -> Result { + get_bit_range!(self.tow_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [WeekNumberValidityStatus][WeekNumberValidityStatus] of the `tow_flags` bitfield. + pub fn set_week_number_validity_status( + &mut self, + week_number_validity_status: WeekNumberValidityStatus, + ) { + set_bit_range!( + &mut self.tow_flags, + week_number_validity_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [TowStatus][self::TowStatus] stored in the `tow_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TowStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TowStatus` were added. + pub fn tow_status(&self) -> Result { + get_bit_range!(self.tow_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TowStatus][TowStatus] of the `tow_flags` bitfield. + pub fn set_tow_status(&mut self, tow_status: TowStatus) { + set_bit_range!(&mut self.tow_flags, tow_status, u8, u8, 2, 0); + } + + /// Gets the [FllStatus][self::FllStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FllStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FllStatus` were added. + pub fn fll_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [FllStatus][FllStatus] of the `track_flags` bitfield. + pub fn set_fll_status(&mut self, fll_status: FllStatus) { + set_bit_range!(&mut self.track_flags, fll_status, u8, u8, 4, 4); + } + + /// Gets the [PllStatus][self::PllStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PllStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PllStatus` were added. + pub fn pll_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [PllStatus][PllStatus] of the `track_flags` bitfield. + pub fn set_pll_status(&mut self, pll_status: PllStatus) { + set_bit_range!(&mut self.track_flags, pll_status, u8, u8, 3, 3); + } + + /// Gets the [TrackingLoopStatus][self::TrackingLoopStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingLoopStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingLoopStatus` were added. + pub fn tracking_loop_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingLoopStatus][TrackingLoopStatus] of the `track_flags` bitfield. + pub fn set_tracking_loop_status(&mut self, tracking_loop_status: TrackingLoopStatus) { + set_bit_range!(&mut self.track_flags, tracking_loop_status, u8, u8, 2, 0); + } + + /// Gets the [AlmanacAvailabilityStatus][self::AlmanacAvailabilityStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AlmanacAvailabilityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AlmanacAvailabilityStatus` were added. + pub fn almanac_availability_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [AlmanacAvailabilityStatus][AlmanacAvailabilityStatus] of the `nav_flags` bitfield. + pub fn set_almanac_availability_status( + &mut self, + almanac_availability_status: AlmanacAvailabilityStatus, + ) { + set_bit_range!( + &mut self.nav_flags, + almanac_availability_status, + u8, + u8, + 4, + 4 + ); + } + + /// Gets the [EphemerisAvailabilityStatus][self::EphemerisAvailabilityStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `EphemerisAvailabilityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `EphemerisAvailabilityStatus` were added. + pub fn ephemeris_availability_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [EphemerisAvailabilityStatus][EphemerisAvailabilityStatus] of the `nav_flags` bitfield. + pub fn set_ephemeris_availability_status( + &mut self, + ephemeris_availability_status: EphemerisAvailabilityStatus, + ) { + set_bit_range!( + &mut self.nav_flags, + ephemeris_availability_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [HealthStatus][self::HealthStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `HealthStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `HealthStatus` were added. + pub fn health_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [HealthStatus][HealthStatus] of the `nav_flags` bitfield. + pub fn set_health_status(&mut self, health_status: HealthStatus) { + set_bit_range!(&mut self.nav_flags, health_status, u8, u8, 2, 0); + } + + /// Gets the [ParameterSets][self::ParameterSets] stored in the `pset_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ParameterSets` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ParameterSets` were added. + pub fn parameter_sets(&self) -> Result { + get_bit_range!(self.pset_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [ParameterSets][ParameterSets] of the `pset_flags` bitfield. + pub fn set_parameter_sets(&mut self, parameter_sets: ParameterSets) { + set_bit_range!(&mut self.pset_flags, parameter_sets, u8, u8, 2, 0); + } + + /// Gets the [ClockValidityStatus][self::ClockValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ClockValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ClockValidityStatus` were added. + pub fn clock_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [ClockValidityStatus][ClockValidityStatus] of the `misc_flags` bitfield. + pub fn set_clock_validity_status(&mut self, clock_validity_status: ClockValidityStatus) { + set_bit_range!(&mut self.misc_flags, clock_validity_status, u8, u8, 5, 5); + } + + /// Gets the [PseudorangeValidityStatus][self::PseudorangeValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PseudorangeValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PseudorangeValidityStatus` were added. + pub fn pseudorange_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [PseudorangeValidityStatus][PseudorangeValidityStatus] of the `misc_flags` bitfield. + pub fn set_pseudorange_validity_status( + &mut self, + pseudorange_validity_status: PseudorangeValidityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + pseudorange_validity_status, + u8, + u8, + 4, + 4 + ); + } + + /// Gets the [AccelerationValidityStatus][self::AccelerationValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AccelerationValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AccelerationValidityStatus` were added. + pub fn acceleration_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [AccelerationValidityStatus][AccelerationValidityStatus] of the `misc_flags` bitfield. + pub fn set_acceleration_validity_status( + &mut self, + acceleration_validity_status: AccelerationValidityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + acceleration_validity_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [CarrierHalfCycleAmbiguityStatus][self::CarrierHalfCycleAmbiguityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CarrierHalfCycleAmbiguityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CarrierHalfCycleAmbiguityStatus` were added. + pub fn carrier_half_cycle_ambiguity_status( + &self, + ) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 2, 2).try_into() + } + + /// Set the bitrange corresponding to the [CarrierHalfCycleAmbiguityStatus][CarrierHalfCycleAmbiguityStatus] of the `misc_flags` bitfield. + pub fn set_carrier_half_cycle_ambiguity_status( + &mut self, + carrier_half_cycle_ambiguity_status: CarrierHalfCycleAmbiguityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + carrier_half_cycle_ambiguity_status, + u8, + u8, + 2, + 2 + ); + } + + /// Gets the [TrackingChannelStatus][self::TrackingChannelStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingChannelStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingChannelStatus` were added. + pub fn tracking_channel_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingChannelStatus][TrackingChannelStatus] of the `misc_flags` bitfield. + pub fn set_tracking_channel_status( + &mut self, + tracking_channel_status: TrackingChannelStatus, + ) { + set_bit_range!(&mut self.misc_flags, tracking_channel_status, u8, u8, 1, 0); + } + } + + impl ConcreteMessage for MsgTrackingStateDetailedDep { + const MESSAGE_TYPE: u16 = 17; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DETAILED_DEP"; + } + + impl SbpMessage for MsgTrackingStateDetailedDep { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + } + + impl TryFrom for MsgTrackingStateDetailedDep { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingStateDetailedDep(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } + } + + impl WireFormat for MsgTrackingStateDetailedDep { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.recv_time) + + WireFormat::len(&self.tot) + + WireFormat::len(&self.p) + + WireFormat::len(&self.p_std) + + WireFormat::len(&self.l) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.doppler) + + WireFormat::len(&self.doppler_std) + + WireFormat::len(&self.uptime) + + WireFormat::len(&self.clock_offset) + + WireFormat::len(&self.clock_drift) + + WireFormat::len(&self.corr_spacing) + + WireFormat::len(&self.acceleration) + + WireFormat::len(&self.sync_flags) + + WireFormat::len(&self.tow_flags) + + WireFormat::len(&self.track_flags) + + WireFormat::len(&self.nav_flags) + + WireFormat::len(&self.pset_flags) + + WireFormat::len(&self.misc_flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.recv_time, buf); + WireFormat::write(&self.tot, buf); + WireFormat::write(&self.p, buf); + WireFormat::write(&self.p_std, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.doppler, buf); + WireFormat::write(&self.doppler_std, buf); + WireFormat::write(&self.uptime, buf); + WireFormat::write(&self.clock_offset, buf); + WireFormat::write(&self.clock_drift, buf); + WireFormat::write(&self.corr_spacing, buf); + WireFormat::write(&self.acceleration, buf); + WireFormat::write(&self.sync_flags, buf); + WireFormat::write(&self.tow_flags, buf); + WireFormat::write(&self.track_flags, buf); + WireFormat::write(&self.nav_flags, buf); + WireFormat::write(&self.pset_flags, buf); + WireFormat::write(&self.misc_flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingStateDetailedDep { + sender_id: None, + recv_time: WireFormat::parse_unchecked(buf), + tot: WireFormat::parse_unchecked(buf), + p: WireFormat::parse_unchecked(buf), + p_std: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + doppler: WireFormat::parse_unchecked(buf), + doppler_std: WireFormat::parse_unchecked(buf), + uptime: WireFormat::parse_unchecked(buf), + clock_offset: WireFormat::parse_unchecked(buf), + clock_drift: WireFormat::parse_unchecked(buf), + corr_spacing: WireFormat::parse_unchecked(buf), + acceleration: WireFormat::parse_unchecked(buf), + sync_flags: WireFormat::parse_unchecked(buf), + tow_flags: WireFormat::parse_unchecked(buf), + track_flags: WireFormat::parse_unchecked(buf), + nav_flags: WireFormat::parse_unchecked(buf), + pset_flags: WireFormat::parse_unchecked(buf), + misc_flags: WireFormat::parse_unchecked(buf), + } + } + } + + /// Synchronization status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SynchronizationStatus { + /// No synchronization + NoSynchronization = 0, + + /// Bit synchronization + BitSynchronization = 1, + + /// Word synchronization (L1 C/A only) + WordSynchronization = 2, + + /// Sub-frame synchronization (L1 C/A) / message synchronization (L2C) + SubFrameSynchronizationMessageSynchronization = 3, + } + + impl std::fmt::Display for SynchronizationStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SynchronizationStatus::NoSynchronization => f.write_str("No synchronization"), + SynchronizationStatus::BitSynchronization => f.write_str("Bit synchronization"), + SynchronizationStatus::WordSynchronization => { + f.write_str("Word synchronization (L1 C/A only)") + } + SynchronizationStatus::SubFrameSynchronizationMessageSynchronization => f + .write_str( + "Sub-frame synchronization (L1 C/A) / message synchronization (L2C) +", + ), + } + } + } + + impl TryFrom for SynchronizationStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SynchronizationStatus::NoSynchronization), + 1 => Ok(SynchronizationStatus::BitSynchronization), + 2 => Ok(SynchronizationStatus::WordSynchronization), + 3 => Ok(SynchronizationStatus::SubFrameSynchronizationMessageSynchronization), + i => Err(i), + } + } + } + + /// Week number validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum WeekNumberValidityStatus { + /// Week number is not valid + WeekNumberIsNotValid = 0, + + /// Week number is valid + WeekNumberIsValid = 1, + } + + impl std::fmt::Display for WeekNumberValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + WeekNumberValidityStatus::WeekNumberIsNotValid => { + f.write_str("Week number is not valid") + } + WeekNumberValidityStatus::WeekNumberIsValid => f.write_str("Week number is valid"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for WeekNumberValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(WeekNumberValidityStatus::WeekNumberIsNotValid), + 1 => Ok(WeekNumberValidityStatus::WeekNumberIsValid), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// TOW status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TowStatus { + /// TOW is not available + TowIsNotAvailable = 0, + + /// Decoded TOW is available + DecodedTowIsAvailable = 1, + + /// Propagated TOW is available + PropagatedTowIsAvailable = 2, + } + + impl std::fmt::Display for TowStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TowStatus::TowIsNotAvailable => f.write_str("TOW is not available"), + TowStatus::DecodedTowIsAvailable => f.write_str("Decoded TOW is available"), + TowStatus::PropagatedTowIsAvailable => f.write_str("Propagated TOW is available"), + } + } + } + + impl TryFrom for TowStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TowStatus::TowIsNotAvailable), + 1 => Ok(TowStatus::DecodedTowIsAvailable), + 2 => Ok(TowStatus::PropagatedTowIsAvailable), + i => Err(i), + } + } + } + + /// FLL status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FllStatus { + /// FLL is inactive + FllIsInactive = 0, + + /// FLL is active + FllIsActive = 1, + } + + impl std::fmt::Display for FllStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FllStatus::FllIsInactive => f.write_str("FLL is inactive"), + FllStatus::FllIsActive => f.write_str("FLL is active"), + } + } + } + + impl TryFrom for FllStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FllStatus::FllIsInactive), + 1 => Ok(FllStatus::FllIsActive), + i => Err(i), + } + } + } + + /// PLL status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PllStatus { + /// PLL is inactive + PllIsInactive = 0, + + /// PLL is active + PllIsActive = 1, + } + + impl std::fmt::Display for PllStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PllStatus::PllIsInactive => f.write_str("PLL is inactive"), + PllStatus::PllIsActive => f.write_str("PLL is active"), + } + } + } + + impl TryFrom for PllStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PllStatus::PllIsInactive), + 1 => Ok(PllStatus::PllIsActive), + i => Err(i), + } + } + } + + /// Tracking loop status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingLoopStatus { + /// No locks + NoLocks = 0, + + /// FLL/DLL lock + FlldllLock = 1, + + /// PLL optimistic lock + PllOptimisticLock = 2, + + /// PLL pessimistic lock + PllPessimisticLock = 3, + } + + impl std::fmt::Display for TrackingLoopStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingLoopStatus::NoLocks => f.write_str("No locks"), + TrackingLoopStatus::FlldllLock => f.write_str("FLL/DLL lock"), + TrackingLoopStatus::PllOptimisticLock => f.write_str("PLL optimistic lock"), + TrackingLoopStatus::PllPessimisticLock => f.write_str("PLL pessimistic lock"), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for TrackingLoopStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingLoopStatus::NoLocks), + 1 => Ok(TrackingLoopStatus::FlldllLock), + 2 => Ok(TrackingLoopStatus::PllOptimisticLock), + 3 => Ok(TrackingLoopStatus::PllPessimisticLock), + i => Err(i), + } + } + } + + /// Almanac availability status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AlmanacAvailabilityStatus { + /// Almanac is not available + AlmanacIsNotAvailable = 0, + + /// Almanac is available + AlmanacIsAvailable = 1, + } + + impl std::fmt::Display for AlmanacAvailabilityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AlmanacAvailabilityStatus::AlmanacIsNotAvailable => { + f.write_str("Almanac is not available") + } + AlmanacAvailabilityStatus::AlmanacIsAvailable => { + f.write_str("Almanac is available") + } + } + } + } + + impl TryFrom for AlmanacAvailabilityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AlmanacAvailabilityStatus::AlmanacIsNotAvailable), + 1 => Ok(AlmanacAvailabilityStatus::AlmanacIsAvailable), + i => Err(i), + } + } + } + + /// Ephemeris availability status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum EphemerisAvailabilityStatus { + /// Ephemeris is not available + EphemerisIsNotAvailable = 0, + + /// Ephemeris is available + EphemerisIsAvailable = 1, + } + + impl std::fmt::Display for EphemerisAvailabilityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EphemerisAvailabilityStatus::EphemerisIsNotAvailable => { + f.write_str("Ephemeris is not available") + } + EphemerisAvailabilityStatus::EphemerisIsAvailable => { + f.write_str("Ephemeris is available") + } + } + } + } + + impl TryFrom for EphemerisAvailabilityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(EphemerisAvailabilityStatus::EphemerisIsNotAvailable), + 1 => Ok(EphemerisAvailabilityStatus::EphemerisIsAvailable), + i => Err(i), + } + } + } + + /// Health status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum HealthStatus { + /// Health is unknown + HealthIsUnknown = 0, + + /// Signal is unhealthy + SignalIsUnhealthy = 1, + + /// Signal is healthy + SignalIsHealthy = 2, + } + + impl std::fmt::Display for HealthStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + HealthStatus::HealthIsUnknown => f.write_str("Health is unknown"), + HealthStatus::SignalIsUnhealthy => f.write_str("Signal is unhealthy"), + HealthStatus::SignalIsHealthy => f.write_str("Signal is healthy"), + } + } + } + + impl TryFrom for HealthStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(HealthStatus::HealthIsUnknown), + 1 => Ok(HealthStatus::SignalIsUnhealthy), + 2 => Ok(HealthStatus::SignalIsHealthy), + i => Err(i), + } + } + } + + /// Parameter sets. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ParameterSets { + /// 1 ms integration time + _1MsIntegrationTime = 0, + + /// 5 ms integration time + _5MsIntegrationTime = 1, + + /// 10 ms integration time + _10MsIntegrationTime = 2, + + /// 20 ms integration time + _20MsIntegrationTime = 3, + } + + impl std::fmt::Display for ParameterSets { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParameterSets::_1MsIntegrationTime => f.write_str("1 ms integration time"), + ParameterSets::_5MsIntegrationTime => f.write_str("5 ms integration time"), + ParameterSets::_10MsIntegrationTime => f.write_str("10 ms integration time"), + ParameterSets::_20MsIntegrationTime => f.write_str("20 ms integration time"), + } + } + } + + impl TryFrom for ParameterSets { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ParameterSets::_1MsIntegrationTime), + 1 => Ok(ParameterSets::_5MsIntegrationTime), + 2 => Ok(ParameterSets::_10MsIntegrationTime), + 3 => Ok(ParameterSets::_20MsIntegrationTime), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Clock validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ClockValidityStatus { + /// Clock offset and drift is not valid + ClockOffsetAndDriftIsNotValid = 0, + + /// Clock offset and drift is valid + ClockOffsetAndDriftIsValid = 1, } -} -impl TryFrom for MsgMeasurementState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgMeasurementState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for ClockValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ClockValidityStatus::ClockOffsetAndDriftIsNotValid => { + f.write_str("Clock offset and drift is not valid") + } + ClockValidityStatus::ClockOffsetAndDriftIsValid => { + f.write_str("Clock offset and drift is valid") + } + } } } -} -impl WireFormat for MsgMeasurementState { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.states) + impl TryFrom for ClockValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ClockValidityStatus::ClockOffsetAndDriftIsNotValid), + 1 => Ok(ClockValidityStatus::ClockOffsetAndDriftIsValid), + i => Err(i), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.states, buf); + + /// Pseudorange validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PseudorangeValidityStatus { + /// Pseudorange is not valid + PseudorangeIsNotValid = 0, + + /// Pseudorange is valid + PseudorangeIsValid = 1, } - fn parse_unchecked(buf: &mut B) -> Self { - MsgMeasurementState { - sender_id: None, - states: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for PseudorangeValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PseudorangeValidityStatus::PseudorangeIsNotValid => { + f.write_str("Pseudorange is not valid") + } + PseudorangeValidityStatus::PseudorangeIsValid => { + f.write_str("Pseudorange is valid") + } + } } } -} -/// Tracking channel correlations -/// -/// When enabled, a tracking channel can output the correlations at each -/// update interval. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingIq { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Tracking channel of origin - #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] - pub channel: u8, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Early, Prompt and Late correlations - #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] - pub corrs: [TrackingChannelCorrelation; 3], -} + impl TryFrom for PseudorangeValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PseudorangeValidityStatus::PseudorangeIsNotValid), + 1 => Ok(PseudorangeValidityStatus::PseudorangeIsValid), + i => Err(i), + } + } + } -impl ConcreteMessage for MsgTrackingIq { - const MESSAGE_TYPE: u16 = 45; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ"; -} + /// Acceleration validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AccelerationValidityStatus { + /// Acceleration is not valid + AccelerationIsNotValid = 0, -impl SbpMessage for MsgTrackingIq { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Acceleration is valid + AccelerationIsValid = 1, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for AccelerationValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AccelerationValidityStatus::AccelerationIsNotValid => { + f.write_str("Acceleration is not valid") + } + AccelerationValidityStatus::AccelerationIsValid => { + f.write_str("Acceleration is valid") + } + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for AccelerationValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AccelerationValidityStatus::AccelerationIsNotValid), + 1 => Ok(AccelerationValidityStatus::AccelerationIsValid), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Carrier half cycle ambiguity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CarrierHalfCycleAmbiguityStatus { + /// Unresolved + Unresolved = 0, + + /// Resolved + Resolved = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for CarrierHalfCycleAmbiguityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CarrierHalfCycleAmbiguityStatus::Unresolved => f.write_str("Unresolved"), + CarrierHalfCycleAmbiguityStatus::Resolved => f.write_str("Resolved"), + } + } } -} -impl TryFrom for MsgTrackingIq { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingIq(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for CarrierHalfCycleAmbiguityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CarrierHalfCycleAmbiguityStatus::Unresolved), + 1 => Ok(CarrierHalfCycleAmbiguityStatus::Resolved), + i => Err(i), + } } } -} -impl WireFormat for MsgTrackingIq { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + <[TrackingChannelCorrelation; 3] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.channel) + WireFormat::len(&self.sid) + WireFormat::len(&self.corrs) + /// Tracking channel status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingChannelStatus { + /// Re-acquisition + ReAcquisition = 0, + + /// Running + Running = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.channel, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.corrs, buf); + + impl std::fmt::Display for TrackingChannelStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingChannelStatus::ReAcquisition => f.write_str("Re-acquisition"), + TrackingChannelStatus::Running => f.write_str("Running"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingIq { - sender_id: None, - channel: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - corrs: WireFormat::parse_unchecked(buf), + + impl TryFrom for TrackingChannelStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingChannelStatus::ReAcquisition), + 1 => Ok(TrackingChannelStatus::Running), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingIqDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Tracking channel of origin - #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] - pub channel: u8, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Early, Prompt and Late correlations - #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] - pub corrs: [TrackingChannelCorrelationDep; 3], -} +pub mod msg_tracking_state_detailed_dep_a { + #![allow(unused_imports)] -impl ConcreteMessage for MsgTrackingIqDepA { - const MESSAGE_TYPE: u16 = 28; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ_DEP_A"; -} + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl SbpMessage for MsgTrackingIqDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// Detailed signal tracking channel states. DEPRECATED + /// + /// The tracking message returns a set tracking channel parameters for a + /// single tracking channel useful for debugging issues. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgTrackingStateDetailedDepA { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Receiver clock time. + #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] + pub recv_time: u64, + /// Time of transmission of signal from satellite. TOW only valid when TOW + /// status is decoded or propagated. WN only valid when week number valid + /// flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tot")))] + pub tot: GpsTime, + /// Pseudorange observation. Valid only when pseudorange valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] + pub p: u32, + /// Pseudorange observation standard deviation. Valid only when pseudorange + /// valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "P_std")))] + pub p_std: u16, + /// Carrier phase observation with typical sign convention. Valid only when + /// PLL pessimistic lock is achieved. + #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] + pub l: CarrierPhase, + /// Carrier-to-Noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + /// Lock time. It is encoded according to DF402 from the RTCM 10403.2 + /// Amendment 2 specification. Valid values range from 0 to 15. + #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] + pub lock: u16, + /// GNSS signal identifier. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Carrier Doppler frequency. + #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler")))] + pub doppler: i32, + /// Carrier Doppler frequency standard deviation. + #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler_std")))] + pub doppler_std: u16, + /// Number of seconds of continuous tracking. Specifies how much time signal + /// is in continuous track. + #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] + pub uptime: u32, + /// TCXO clock offset. Valid only when valid clock valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_offset")))] + pub clock_offset: i16, + /// TCXO clock drift. Valid only when valid clock valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_drift")))] + pub clock_drift: i16, + /// Early-Prompt (EP) and Prompt-Late (PL) correlators spacing. + #[cfg_attr(feature = "serde", serde(rename(serialize = "corr_spacing")))] + pub corr_spacing: u16, + /// Acceleration. Valid only when acceleration valid flag is set. + #[cfg_attr(feature = "serde", serde(rename(serialize = "acceleration")))] + pub acceleration: i8, + /// Synchronization status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "sync_flags")))] + pub sync_flags: u8, + /// TOW status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_flags")))] + pub tow_flags: u8, + /// Tracking loop status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "track_flags")))] + pub track_flags: u8, + /// Navigation data status flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "nav_flags")))] + pub nav_flags: u8, + /// Parameters sets flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "pset_flags")))] + pub pset_flags: u8, + /// Miscellaneous flags. + #[cfg_attr(feature = "serde", serde(rename(serialize = "misc_flags")))] + pub misc_flags: u8, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl MsgTrackingStateDetailedDepA { + /// Gets the [SynchronizationStatus][self::SynchronizationStatus] stored in the `sync_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SynchronizationStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SynchronizationStatus` were added. + pub fn synchronization_status(&self) -> Result { + get_bit_range!(self.sync_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [SynchronizationStatus][SynchronizationStatus] of the `sync_flags` bitfield. + pub fn set_synchronization_status( + &mut self, + synchronization_status: SynchronizationStatus, + ) { + set_bit_range!(&mut self.sync_flags, synchronization_status, u8, u8, 2, 0); + } + + /// Gets the [WeekNumberValidityStatus][self::WeekNumberValidityStatus] stored in the `tow_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `WeekNumberValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `WeekNumberValidityStatus` were added. + pub fn week_number_validity_status(&self) -> Result { + get_bit_range!(self.tow_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [WeekNumberValidityStatus][WeekNumberValidityStatus] of the `tow_flags` bitfield. + pub fn set_week_number_validity_status( + &mut self, + week_number_validity_status: WeekNumberValidityStatus, + ) { + set_bit_range!( + &mut self.tow_flags, + week_number_validity_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [TowStatus][self::TowStatus] stored in the `tow_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TowStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TowStatus` were added. + pub fn tow_status(&self) -> Result { + get_bit_range!(self.tow_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TowStatus][TowStatus] of the `tow_flags` bitfield. + pub fn set_tow_status(&mut self, tow_status: TowStatus) { + set_bit_range!(&mut self.tow_flags, tow_status, u8, u8, 2, 0); + } + + /// Gets the [FllStatus][self::FllStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `FllStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `FllStatus` were added. + pub fn fll_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [FllStatus][FllStatus] of the `track_flags` bitfield. + pub fn set_fll_status(&mut self, fll_status: FllStatus) { + set_bit_range!(&mut self.track_flags, fll_status, u8, u8, 4, 4); + } + + /// Gets the [PllStatus][self::PllStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PllStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PllStatus` were added. + pub fn pll_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [PllStatus][PllStatus] of the `track_flags` bitfield. + pub fn set_pll_status(&mut self, pll_status: PllStatus) { + set_bit_range!(&mut self.track_flags, pll_status, u8, u8, 3, 3); + } + + /// Gets the [TrackingLoopStatus][self::TrackingLoopStatus] stored in the `track_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingLoopStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingLoopStatus` were added. + pub fn tracking_loop_status(&self) -> Result { + get_bit_range!(self.track_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingLoopStatus][TrackingLoopStatus] of the `track_flags` bitfield. + pub fn set_tracking_loop_status(&mut self, tracking_loop_status: TrackingLoopStatus) { + set_bit_range!(&mut self.track_flags, tracking_loop_status, u8, u8, 2, 0); + } + + /// Gets the [AlmanacAvailabilityStatus][self::AlmanacAvailabilityStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AlmanacAvailabilityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AlmanacAvailabilityStatus` were added. + pub fn almanac_availability_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [AlmanacAvailabilityStatus][AlmanacAvailabilityStatus] of the `nav_flags` bitfield. + pub fn set_almanac_availability_status( + &mut self, + almanac_availability_status: AlmanacAvailabilityStatus, + ) { + set_bit_range!( + &mut self.nav_flags, + almanac_availability_status, + u8, + u8, + 4, + 4 + ); + } + + /// Gets the [EphemerisAvailabilityStatus][self::EphemerisAvailabilityStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `EphemerisAvailabilityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `EphemerisAvailabilityStatus` were added. + pub fn ephemeris_availability_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [EphemerisAvailabilityStatus][EphemerisAvailabilityStatus] of the `nav_flags` bitfield. + pub fn set_ephemeris_availability_status( + &mut self, + ephemeris_availability_status: EphemerisAvailabilityStatus, + ) { + set_bit_range!( + &mut self.nav_flags, + ephemeris_availability_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [HealthStatus][self::HealthStatus] stored in the `nav_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `HealthStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `HealthStatus` were added. + pub fn health_status(&self) -> Result { + get_bit_range!(self.nav_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [HealthStatus][HealthStatus] of the `nav_flags` bitfield. + pub fn set_health_status(&mut self, health_status: HealthStatus) { + set_bit_range!(&mut self.nav_flags, health_status, u8, u8, 2, 0); + } + + /// Gets the [ParameterSets][self::ParameterSets] stored in the `pset_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ParameterSets` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ParameterSets` were added. + pub fn parameter_sets(&self) -> Result { + get_bit_range!(self.pset_flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [ParameterSets][ParameterSets] of the `pset_flags` bitfield. + pub fn set_parameter_sets(&mut self, parameter_sets: ParameterSets) { + set_bit_range!(&mut self.pset_flags, parameter_sets, u8, u8, 2, 0); + } + + /// Gets the [ClockValidityStatus][self::ClockValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `ClockValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `ClockValidityStatus` were added. + pub fn clock_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 5, 5).try_into() + } + + /// Set the bitrange corresponding to the [ClockValidityStatus][ClockValidityStatus] of the `misc_flags` bitfield. + pub fn set_clock_validity_status(&mut self, clock_validity_status: ClockValidityStatus) { + set_bit_range!(&mut self.misc_flags, clock_validity_status, u8, u8, 5, 5); + } + + /// Gets the [PseudorangeValidityStatus][self::PseudorangeValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `PseudorangeValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `PseudorangeValidityStatus` were added. + pub fn pseudorange_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 4, 4).try_into() + } + + /// Set the bitrange corresponding to the [PseudorangeValidityStatus][PseudorangeValidityStatus] of the `misc_flags` bitfield. + pub fn set_pseudorange_validity_status( + &mut self, + pseudorange_validity_status: PseudorangeValidityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + pseudorange_validity_status, + u8, + u8, + 4, + 4 + ); + } + + /// Gets the [AccelerationValidityStatus][self::AccelerationValidityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `AccelerationValidityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `AccelerationValidityStatus` were added. + pub fn acceleration_validity_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 3, 3).try_into() + } + + /// Set the bitrange corresponding to the [AccelerationValidityStatus][AccelerationValidityStatus] of the `misc_flags` bitfield. + pub fn set_acceleration_validity_status( + &mut self, + acceleration_validity_status: AccelerationValidityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + acceleration_validity_status, + u8, + u8, + 3, + 3 + ); + } + + /// Gets the [CarrierHalfCycleAmbiguityStatus][self::CarrierHalfCycleAmbiguityStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `CarrierHalfCycleAmbiguityStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `CarrierHalfCycleAmbiguityStatus` were added. + pub fn carrier_half_cycle_ambiguity_status( + &self, + ) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 2, 2).try_into() + } + + /// Set the bitrange corresponding to the [CarrierHalfCycleAmbiguityStatus][CarrierHalfCycleAmbiguityStatus] of the `misc_flags` bitfield. + pub fn set_carrier_half_cycle_ambiguity_status( + &mut self, + carrier_half_cycle_ambiguity_status: CarrierHalfCycleAmbiguityStatus, + ) { + set_bit_range!( + &mut self.misc_flags, + carrier_half_cycle_ambiguity_status, + u8, + u8, + 2, + 2 + ); + } + + /// Gets the [TrackingChannelStatus][self::TrackingChannelStatus] stored in the `misc_flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingChannelStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingChannelStatus` were added. + pub fn tracking_channel_status(&self) -> Result { + get_bit_range!(self.misc_flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingChannelStatus][TrackingChannelStatus] of the `misc_flags` bitfield. + pub fn set_tracking_channel_status( + &mut self, + tracking_channel_status: TrackingChannelStatus, + ) { + set_bit_range!(&mut self.misc_flags, tracking_channel_status, u8, u8, 1, 0); + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgTrackingStateDetailedDepA { + const MESSAGE_TYPE: u16 = 33; + const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DETAILED_DEP_A"; } -} -impl TryFrom for MsgTrackingIqDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingIqDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgTrackingStateDetailedDepA { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgTrackingIqDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + <[TrackingChannelCorrelationDep; 3] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.channel) + WireFormat::len(&self.sid) + WireFormat::len(&self.corrs) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.channel, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.corrs, buf); + impl TryFrom for MsgTrackingStateDetailedDepA { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgTrackingStateDetailedDepA(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingIqDepA { - sender_id: None, - channel: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - corrs: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgTrackingStateDetailedDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.recv_time) + + WireFormat::len(&self.tot) + + WireFormat::len(&self.p) + + WireFormat::len(&self.p_std) + + WireFormat::len(&self.l) + + WireFormat::len(&self.cn0) + + WireFormat::len(&self.lock) + + WireFormat::len(&self.sid) + + WireFormat::len(&self.doppler) + + WireFormat::len(&self.doppler_std) + + WireFormat::len(&self.uptime) + + WireFormat::len(&self.clock_offset) + + WireFormat::len(&self.clock_drift) + + WireFormat::len(&self.corr_spacing) + + WireFormat::len(&self.acceleration) + + WireFormat::len(&self.sync_flags) + + WireFormat::len(&self.tow_flags) + + WireFormat::len(&self.track_flags) + + WireFormat::len(&self.nav_flags) + + WireFormat::len(&self.pset_flags) + + WireFormat::len(&self.misc_flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.recv_time, buf); + WireFormat::write(&self.tot, buf); + WireFormat::write(&self.p, buf); + WireFormat::write(&self.p_std, buf); + WireFormat::write(&self.l, buf); + WireFormat::write(&self.cn0, buf); + WireFormat::write(&self.lock, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.doppler, buf); + WireFormat::write(&self.doppler_std, buf); + WireFormat::write(&self.uptime, buf); + WireFormat::write(&self.clock_offset, buf); + WireFormat::write(&self.clock_drift, buf); + WireFormat::write(&self.corr_spacing, buf); + WireFormat::write(&self.acceleration, buf); + WireFormat::write(&self.sync_flags, buf); + WireFormat::write(&self.tow_flags, buf); + WireFormat::write(&self.track_flags, buf); + WireFormat::write(&self.nav_flags, buf); + WireFormat::write(&self.pset_flags, buf); + WireFormat::write(&self.misc_flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgTrackingStateDetailedDepA { + sender_id: None, + recv_time: WireFormat::parse_unchecked(buf), + tot: WireFormat::parse_unchecked(buf), + p: WireFormat::parse_unchecked(buf), + p_std: WireFormat::parse_unchecked(buf), + l: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + lock: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + doppler: WireFormat::parse_unchecked(buf), + doppler_std: WireFormat::parse_unchecked(buf), + uptime: WireFormat::parse_unchecked(buf), + clock_offset: WireFormat::parse_unchecked(buf), + clock_drift: WireFormat::parse_unchecked(buf), + corr_spacing: WireFormat::parse_unchecked(buf), + acceleration: WireFormat::parse_unchecked(buf), + sync_flags: WireFormat::parse_unchecked(buf), + tow_flags: WireFormat::parse_unchecked(buf), + track_flags: WireFormat::parse_unchecked(buf), + nav_flags: WireFormat::parse_unchecked(buf), + pset_flags: WireFormat::parse_unchecked(buf), + misc_flags: WireFormat::parse_unchecked(buf), + } } } -} -/// Tracking channel correlations -/// -/// When enabled, a tracking channel can output the correlations at each -/// update interval. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingIqDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Tracking channel of origin - #[cfg_attr(feature = "serde", serde(rename(serialize = "channel")))] - pub channel: u8, - /// GNSS signal identifier - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Early, Prompt and Late correlations - #[cfg_attr(feature = "serde", serde(rename(serialize = "corrs")))] - pub corrs: [TrackingChannelCorrelationDep; 3], -} + /// Synchronization status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SynchronizationStatus { + /// No synchronization + NoSynchronization = 0, -impl ConcreteMessage for MsgTrackingIqDepB { - const MESSAGE_TYPE: u16 = 44; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_IQ_DEP_B"; -} + /// Bit synchronization + BitSynchronization = 1, -impl SbpMessage for MsgTrackingIqDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id - } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + /// Word synchronization (L1 C/A only) + WordSynchronization = 2, + + /// Sub-frame synchronization (L1 C/A) / message synchronization (L2C) + SubFrameSynchronizationMessageSynchronization = 3, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for SynchronizationStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SynchronizationStatus::NoSynchronization => f.write_str("No synchronization"), + SynchronizationStatus::BitSynchronization => f.write_str("Bit synchronization"), + SynchronizationStatus::WordSynchronization => { + f.write_str("Word synchronization (L1 C/A only)") + } + SynchronizationStatus::SubFrameSynchronizationMessageSynchronization => f + .write_str( + "Sub-frame synchronization (L1 C/A) / message synchronization (L2C) +", + ), + } + } } -} -impl TryFrom for MsgTrackingIqDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingIqDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for SynchronizationStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SynchronizationStatus::NoSynchronization), + 1 => Ok(SynchronizationStatus::BitSynchronization), + 2 => Ok(SynchronizationStatus::WordSynchronization), + 3 => Ok(SynchronizationStatus::SubFrameSynchronizationMessageSynchronization), + i => Err(i), + } } } -} -impl WireFormat for MsgTrackingIqDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + <[TrackingChannelCorrelationDep; 3] as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.channel) + WireFormat::len(&self.sid) + WireFormat::len(&self.corrs) + /// Week number validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum WeekNumberValidityStatus { + /// Week number is not valid + WeekNumberIsNotValid = 0, + + /// Week number is valid + WeekNumberIsValid = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.channel, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.corrs, buf); + + impl std::fmt::Display for WeekNumberValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + WeekNumberValidityStatus::WeekNumberIsNotValid => { + f.write_str("Week number is not valid") + } + WeekNumberValidityStatus::WeekNumberIsValid => f.write_str("Week number is valid"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingIqDepB { - sender_id: None, - channel: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - corrs: WireFormat::parse_unchecked(buf), + + impl TryFrom for WeekNumberValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(WeekNumberValidityStatus::WeekNumberIsNotValid), + 1 => Ok(WeekNumberValidityStatus::WeekNumberIsValid), + i => Err(i), + } } } -} -/// Signal tracking channel states -/// -/// The tracking message returns a variable-length array of tracking channel -/// states. It reports status and carrier-to-noise density measurements for -/// all tracked satellites. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingState { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Signal tracking channel state - #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] - pub states: Vec, -} + /// TOW status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TowStatus { + /// TOW is not available + TowIsNotAvailable = 0, -impl ConcreteMessage for MsgTrackingState { - const MESSAGE_TYPE: u16 = 65; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE"; -} + /// Decoded TOW is available + DecodedTowIsAvailable = 1, -impl SbpMessage for MsgTrackingState { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Propagated TOW is available + PropagatedTowIsAvailable = 2, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for TowStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TowStatus::TowIsNotAvailable => f.write_str("TOW is not available"), + TowStatus::DecodedTowIsAvailable => f.write_str("Decoded TOW is available"), + TowStatus::PropagatedTowIsAvailable => f.write_str("Propagated TOW is available"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for TowStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TowStatus::TowIsNotAvailable), + 1 => Ok(TowStatus::DecodedTowIsAvailable), + 2 => Ok(TowStatus::PropagatedTowIsAvailable), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// FLL status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum FllStatus { + /// FLL is inactive + FllIsInactive = 0, + + /// FLL is active + FllIsActive = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for FllStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FllStatus::FllIsInactive => f.write_str("FLL is inactive"), + FllStatus::FllIsActive => f.write_str("FLL is active"), + } + } } -} -impl TryFrom for MsgTrackingState { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingState(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for FllStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(FllStatus::FllIsInactive), + 1 => Ok(FllStatus::FllIsActive), + i => Err(i), + } } } -} -impl WireFormat for MsgTrackingState { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.states) + /// PLL status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PllStatus { + /// PLL is inactive + PllIsInactive = 0, + + /// PLL is active + PllIsActive = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.states, buf); + + impl std::fmt::Display for PllStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PllStatus::PllIsInactive => f.write_str("PLL is inactive"), + PllStatus::PllIsActive => f.write_str("PLL is active"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingState { - sender_id: None, - states: WireFormat::parse_unchecked(buf), + + impl TryFrom for PllStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PllStatus::PllIsInactive), + 1 => Ok(PllStatus::PllIsActive), + i => Err(i), + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingStateDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Satellite tracking channel state - #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] - pub states: Vec, -} + /// Tracking loop status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingLoopStatus { + /// No locks + NoLocks = 0, -impl ConcreteMessage for MsgTrackingStateDepA { - const MESSAGE_TYPE: u16 = 22; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DEP_A"; -} + /// FLL/DLL lock + FlldllLock = 1, -impl SbpMessage for MsgTrackingStateDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// PLL optimistic lock + PllOptimisticLock = 2, + + /// PLL pessimistic lock + PllPessimisticLock = 3, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl std::fmt::Display for TrackingLoopStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingLoopStatus::NoLocks => f.write_str("No locks"), + TrackingLoopStatus::FlldllLock => f.write_str("FLL/DLL lock"), + TrackingLoopStatus::PllOptimisticLock => f.write_str("PLL optimistic lock"), + TrackingLoopStatus::PllPessimisticLock => f.write_str("PLL pessimistic lock"), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl TryFrom for TrackingLoopStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingLoopStatus::NoLocks), + 1 => Ok(TrackingLoopStatus::FlldllLock), + 2 => Ok(TrackingLoopStatus::PllOptimisticLock), + 3 => Ok(TrackingLoopStatus::PllPessimisticLock), + i => Err(i), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + /// Almanac availability status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AlmanacAvailabilityStatus { + /// Almanac is not available + AlmanacIsNotAvailable = 0, + + /// Almanac is available + AlmanacIsAvailable = 1, } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl std::fmt::Display for AlmanacAvailabilityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AlmanacAvailabilityStatus::AlmanacIsNotAvailable => { + f.write_str("Almanac is not available") + } + AlmanacAvailabilityStatus::AlmanacIsAvailable => { + f.write_str("Almanac is available") + } + } + } } -} -impl TryFrom for MsgTrackingStateDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingStateDepA(m) => Ok(m), - _ => Err(TryFromSbpError), + impl TryFrom for AlmanacAvailabilityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AlmanacAvailabilityStatus::AlmanacIsNotAvailable), + 1 => Ok(AlmanacAvailabilityStatus::AlmanacIsAvailable), + i => Err(i), + } } } -} -impl WireFormat for MsgTrackingStateDepA { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.states) + /// Ephemeris availability status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum EphemerisAvailabilityStatus { + /// Ephemeris is not available + EphemerisIsNotAvailable = 0, + + /// Ephemeris is available + EphemerisIsAvailable = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.states, buf); + + impl std::fmt::Display for EphemerisAvailabilityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EphemerisAvailabilityStatus::EphemerisIsNotAvailable => { + f.write_str("Ephemeris is not available") + } + EphemerisAvailabilityStatus::EphemerisIsAvailable => { + f.write_str("Ephemeris is available") + } + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingStateDepA { - sender_id: None, - states: WireFormat::parse_unchecked(buf), + + impl TryFrom for EphemerisAvailabilityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(EphemerisAvailabilityStatus::EphemerisIsNotAvailable), + 1 => Ok(EphemerisAvailabilityStatus::EphemerisIsAvailable), + i => Err(i), + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingStateDepB { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Signal tracking channel state - #[cfg_attr(feature = "serde", serde(rename(serialize = "states")))] - pub states: Vec, -} + /// Health status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum HealthStatus { + /// Health is unknown + HealthIsUnknown = 0, -impl ConcreteMessage for MsgTrackingStateDepB { - const MESSAGE_TYPE: u16 = 19; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DEP_B"; -} + /// Signal is unhealthy + SignalIsUnhealthy = 1, -impl SbpMessage for MsgTrackingStateDepB { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Signal is healthy + SignalIsHealthy = 2, } - fn sender_id(&self) -> Option { - self.sender_id + + impl std::fmt::Display for HealthStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + HealthStatus::HealthIsUnknown => f.write_str("Health is unknown"), + HealthStatus::SignalIsUnhealthy => f.write_str("Signal is unhealthy"), + HealthStatus::SignalIsHealthy => f.write_str("Signal is healthy"), + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for HealthStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(HealthStatus::HealthIsUnknown), + 1 => Ok(HealthStatus::SignalIsUnhealthy), + 2 => Ok(HealthStatus::SignalIsHealthy), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Parameter sets. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ParameterSets { + /// 1 ms integration time + _1MsIntegrationTime = 0, + + /// 5 ms integration time + _5MsIntegrationTime = 1, + + /// 10 ms integration time + _10MsIntegrationTime = 2, + + /// 20 ms integration time + _20MsIntegrationTime = 3, } -} -impl TryFrom for MsgTrackingStateDepB { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingStateDepB(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for ParameterSets { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParameterSets::_1MsIntegrationTime => f.write_str("1 ms integration time"), + ParameterSets::_5MsIntegrationTime => f.write_str("5 ms integration time"), + ParameterSets::_10MsIntegrationTime => f.write_str("10 ms integration time"), + ParameterSets::_20MsIntegrationTime => f.write_str("20 ms integration time"), + } } } -} -impl WireFormat for MsgTrackingStateDepB { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.states) + impl TryFrom for ParameterSets { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ParameterSets::_1MsIntegrationTime), + 1 => Ok(ParameterSets::_5MsIntegrationTime), + 2 => Ok(ParameterSets::_10MsIntegrationTime), + 3 => Ok(ParameterSets::_20MsIntegrationTime), + i => Err(i), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.states, buf); + + /// Clock validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ClockValidityStatus { + /// Clock offset and drift is not valid + ClockOffsetAndDriftIsNotValid = 0, + + /// Clock offset and drift is valid + ClockOffsetAndDriftIsValid = 1, } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingStateDepB { - sender_id: None, - states: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for ClockValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ClockValidityStatus::ClockOffsetAndDriftIsNotValid => { + f.write_str("Clock offset and drift is not valid") + } + ClockValidityStatus::ClockOffsetAndDriftIsValid => { + f.write_str("Clock offset and drift is valid") + } + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingStateDetailedDep { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Receiver clock time. - #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] - pub recv_time: u64, - /// Time of transmission of signal from satellite. TOW only valid when TOW - /// status is decoded or propagated. WN only valid when week number valid - /// flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tot")))] - pub tot: GpsTimeDep, - /// Pseudorange observation. Valid only when pseudorange valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Pseudorange observation standard deviation. Valid only when pseudorange - /// valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "P_std")))] - pub p_std: u16, - /// Carrier phase observation with typical sign convention. Valid only when - /// PLL pessimistic lock is achieved. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhase, - /// Carrier-to-Noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock time. It is encoded according to DF402 from the RTCM 10403.2 - /// Amendment 2 specification. Valid values range from 0 to 15. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u16, - /// GNSS signal identifier. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Carrier Doppler frequency. - #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler")))] - pub doppler: i32, - /// Carrier Doppler frequency standard deviation. - #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler_std")))] - pub doppler_std: u16, - /// Number of seconds of continuous tracking. Specifies how much time signal - /// is in continuous track. - #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] - pub uptime: u32, - /// TCXO clock offset. Valid only when valid clock valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_offset")))] - pub clock_offset: i16, - /// TCXO clock drift. Valid only when valid clock valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_drift")))] - pub clock_drift: i16, - /// Early-Prompt (EP) and Prompt-Late (PL) correlators spacing. - #[cfg_attr(feature = "serde", serde(rename(serialize = "corr_spacing")))] - pub corr_spacing: u16, - /// Acceleration. Valid only when acceleration valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "acceleration")))] - pub acceleration: i8, - /// Synchronization status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sync_flags")))] - pub sync_flags: u8, - /// TOW status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_flags")))] - pub tow_flags: u8, - /// Tracking loop status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "track_flags")))] - pub track_flags: u8, - /// Navigation data status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "nav_flags")))] - pub nav_flags: u8, - /// Parameters sets flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "pset_flags")))] - pub pset_flags: u8, - /// Miscellaneous flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "misc_flags")))] - pub misc_flags: u8, -} + impl TryFrom for ClockValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(ClockValidityStatus::ClockOffsetAndDriftIsNotValid), + 1 => Ok(ClockValidityStatus::ClockOffsetAndDriftIsValid), + i => Err(i), + } + } + } -impl ConcreteMessage for MsgTrackingStateDetailedDep { - const MESSAGE_TYPE: u16 = 17; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DETAILED_DEP"; -} + /// Pseudorange validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum PseudorangeValidityStatus { + /// Pseudorange is not valid + PseudorangeIsNotValid = 0, -impl SbpMessage for MsgTrackingStateDetailedDep { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + /// Pseudorange is valid + PseudorangeIsValid = 1, } - fn sender_id(&self) -> Option { - self.sender_id + + impl std::fmt::Display for PseudorangeValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PseudorangeValidityStatus::PseudorangeIsNotValid => { + f.write_str("Pseudorange is not valid") + } + PseudorangeValidityStatus::PseudorangeIsValid => { + f.write_str("Pseudorange is valid") + } + } + } } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl TryFrom for PseudorangeValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(PseudorangeValidityStatus::PseudorangeIsNotValid), + 1 => Ok(PseudorangeValidityStatus::PseudorangeIsValid), + i => Err(i), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + /// Acceleration validity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum AccelerationValidityStatus { + /// Acceleration is not valid + AccelerationIsNotValid = 0, + + /// Acceleration is valid + AccelerationIsValid = 1, } -} -impl TryFrom for MsgTrackingStateDetailedDep { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingStateDetailedDep(m) => Ok(m), - _ => Err(TryFromSbpError), + impl std::fmt::Display for AccelerationValidityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AccelerationValidityStatus::AccelerationIsNotValid => { + f.write_str("Acceleration is not valid") + } + AccelerationValidityStatus::AccelerationIsValid => { + f.write_str("Acceleration is valid") + } + } } } -} -impl WireFormat for MsgTrackingStateDetailedDep { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.recv_time) - + WireFormat::len(&self.tot) - + WireFormat::len(&self.p) - + WireFormat::len(&self.p_std) - + WireFormat::len(&self.l) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.doppler) - + WireFormat::len(&self.doppler_std) - + WireFormat::len(&self.uptime) - + WireFormat::len(&self.clock_offset) - + WireFormat::len(&self.clock_drift) - + WireFormat::len(&self.corr_spacing) - + WireFormat::len(&self.acceleration) - + WireFormat::len(&self.sync_flags) - + WireFormat::len(&self.tow_flags) - + WireFormat::len(&self.track_flags) - + WireFormat::len(&self.nav_flags) - + WireFormat::len(&self.pset_flags) - + WireFormat::len(&self.misc_flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.recv_time, buf); - WireFormat::write(&self.tot, buf); - WireFormat::write(&self.p, buf); - WireFormat::write(&self.p_std, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.doppler, buf); - WireFormat::write(&self.doppler_std, buf); - WireFormat::write(&self.uptime, buf); - WireFormat::write(&self.clock_offset, buf); - WireFormat::write(&self.clock_drift, buf); - WireFormat::write(&self.corr_spacing, buf); - WireFormat::write(&self.acceleration, buf); - WireFormat::write(&self.sync_flags, buf); - WireFormat::write(&self.tow_flags, buf); - WireFormat::write(&self.track_flags, buf); - WireFormat::write(&self.nav_flags, buf); - WireFormat::write(&self.pset_flags, buf); - WireFormat::write(&self.misc_flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingStateDetailedDep { - sender_id: None, - recv_time: WireFormat::parse_unchecked(buf), - tot: WireFormat::parse_unchecked(buf), - p: WireFormat::parse_unchecked(buf), - p_std: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - doppler: WireFormat::parse_unchecked(buf), - doppler_std: WireFormat::parse_unchecked(buf), - uptime: WireFormat::parse_unchecked(buf), - clock_offset: WireFormat::parse_unchecked(buf), - clock_drift: WireFormat::parse_unchecked(buf), - corr_spacing: WireFormat::parse_unchecked(buf), - acceleration: WireFormat::parse_unchecked(buf), - sync_flags: WireFormat::parse_unchecked(buf), - tow_flags: WireFormat::parse_unchecked(buf), - track_flags: WireFormat::parse_unchecked(buf), - nav_flags: WireFormat::parse_unchecked(buf), - pset_flags: WireFormat::parse_unchecked(buf), - misc_flags: WireFormat::parse_unchecked(buf), + impl TryFrom for AccelerationValidityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(AccelerationValidityStatus::AccelerationIsNotValid), + 1 => Ok(AccelerationValidityStatus::AccelerationIsValid), + i => Err(i), + } } } -} -/// Detailed signal tracking channel states. DEPRECATED -/// -/// The tracking message returns a set tracking channel parameters for a -/// single tracking channel useful for debugging issues. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgTrackingStateDetailedDepA { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Receiver clock time. - #[cfg_attr(feature = "serde", serde(rename(serialize = "recv_time")))] - pub recv_time: u64, - /// Time of transmission of signal from satellite. TOW only valid when TOW - /// status is decoded or propagated. WN only valid when week number valid - /// flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tot")))] - pub tot: GpsTime, - /// Pseudorange observation. Valid only when pseudorange valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "P")))] - pub p: u32, - /// Pseudorange observation standard deviation. Valid only when pseudorange - /// valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "P_std")))] - pub p_std: u16, - /// Carrier phase observation with typical sign convention. Valid only when - /// PLL pessimistic lock is achieved. - #[cfg_attr(feature = "serde", serde(rename(serialize = "L")))] - pub l: CarrierPhase, - /// Carrier-to-Noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, - /// Lock time. It is encoded according to DF402 from the RTCM 10403.2 - /// Amendment 2 specification. Valid values range from 0 to 15. - #[cfg_attr(feature = "serde", serde(rename(serialize = "lock")))] - pub lock: u16, - /// GNSS signal identifier. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Carrier Doppler frequency. - #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler")))] - pub doppler: i32, - /// Carrier Doppler frequency standard deviation. - #[cfg_attr(feature = "serde", serde(rename(serialize = "doppler_std")))] - pub doppler_std: u16, - /// Number of seconds of continuous tracking. Specifies how much time signal - /// is in continuous track. - #[cfg_attr(feature = "serde", serde(rename(serialize = "uptime")))] - pub uptime: u32, - /// TCXO clock offset. Valid only when valid clock valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_offset")))] - pub clock_offset: i16, - /// TCXO clock drift. Valid only when valid clock valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "clock_drift")))] - pub clock_drift: i16, - /// Early-Prompt (EP) and Prompt-Late (PL) correlators spacing. - #[cfg_attr(feature = "serde", serde(rename(serialize = "corr_spacing")))] - pub corr_spacing: u16, - /// Acceleration. Valid only when acceleration valid flag is set. - #[cfg_attr(feature = "serde", serde(rename(serialize = "acceleration")))] - pub acceleration: i8, - /// Synchronization status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "sync_flags")))] - pub sync_flags: u8, - /// TOW status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow_flags")))] - pub tow_flags: u8, - /// Tracking loop status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "track_flags")))] - pub track_flags: u8, - /// Navigation data status flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "nav_flags")))] - pub nav_flags: u8, - /// Parameters sets flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "pset_flags")))] - pub pset_flags: u8, - /// Miscellaneous flags. - #[cfg_attr(feature = "serde", serde(rename(serialize = "misc_flags")))] - pub misc_flags: u8, -} + /// Carrier half cycle ambiguity status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum CarrierHalfCycleAmbiguityStatus { + /// Unresolved + Unresolved = 0, -impl ConcreteMessage for MsgTrackingStateDetailedDepA { - const MESSAGE_TYPE: u16 = 33; - const MESSAGE_NAME: &'static str = "MSG_TRACKING_STATE_DETAILED_DEP_A"; -} + /// Resolved + Resolved = 1, + } -impl SbpMessage for MsgTrackingStateDetailedDepA { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + impl std::fmt::Display for CarrierHalfCycleAmbiguityStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CarrierHalfCycleAmbiguityStatus::Unresolved => f.write_str("Unresolved"), + CarrierHalfCycleAmbiguityStatus::Resolved => f.write_str("Resolved"), + } + } } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl TryFrom for CarrierHalfCycleAmbiguityStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(CarrierHalfCycleAmbiguityStatus::Unresolved), + 1 => Ok(CarrierHalfCycleAmbiguityStatus::Resolved), + i => Err(i), + } + } } - fn sender_id(&self) -> Option { - self.sender_id + + /// Tracking channel status. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingChannelStatus { + /// Re-acquisition + ReAcquisition = 0, + + /// Running + Running = 1, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl std::fmt::Display for TrackingChannelStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingChannelStatus::ReAcquisition => f.write_str("Re-acquisition"), + TrackingChannelStatus::Running => f.write_str("Running"), + } + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for TrackingChannelStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingChannelStatus::ReAcquisition), + 1 => Ok(TrackingChannelStatus::Running), + i => Err(i), + } + } } } -impl TryFrom for MsgTrackingStateDetailedDepA { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgTrackingStateDetailedDepA(m) => Ok(m), - _ => Err(TryFromSbpError), +pub mod measurement_state { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Measurement Engine signal tracking channel state + /// + /// Measurement Engine tracking channel state for a specific satellite signal + /// and measured signal power. The mesid field for Glonass can either carry + /// the FCN as 100 + FCN where FCN is in \[-7, +6\] or the Slot ID (from 1 to + /// 28). + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MeasurementState { + /// Measurement Engine GNSS signal being tracked (carries either Glonass FCN + /// or SLOT) + #[cfg_attr(feature = "serde", serde(rename(serialize = "mesid")))] + pub mesid: GnssSignal, + /// Carrier-to-Noise density. Zero implies invalid cn0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, + } + + impl WireFormat for MeasurementState { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.mesid) + WireFormat::len(&self.cn0) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.mesid, buf); + WireFormat::write(&self.cn0, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MeasurementState { + mesid: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + } } } } -impl WireFormat for MsgTrackingStateDetailedDepA { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.recv_time) - + WireFormat::len(&self.tot) - + WireFormat::len(&self.p) - + WireFormat::len(&self.p_std) - + WireFormat::len(&self.l) - + WireFormat::len(&self.cn0) - + WireFormat::len(&self.lock) - + WireFormat::len(&self.sid) - + WireFormat::len(&self.doppler) - + WireFormat::len(&self.doppler_std) - + WireFormat::len(&self.uptime) - + WireFormat::len(&self.clock_offset) - + WireFormat::len(&self.clock_drift) - + WireFormat::len(&self.corr_spacing) - + WireFormat::len(&self.acceleration) - + WireFormat::len(&self.sync_flags) - + WireFormat::len(&self.tow_flags) - + WireFormat::len(&self.track_flags) - + WireFormat::len(&self.nav_flags) - + WireFormat::len(&self.pset_flags) - + WireFormat::len(&self.misc_flags) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.recv_time, buf); - WireFormat::write(&self.tot, buf); - WireFormat::write(&self.p, buf); - WireFormat::write(&self.p_std, buf); - WireFormat::write(&self.l, buf); - WireFormat::write(&self.cn0, buf); - WireFormat::write(&self.lock, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.doppler, buf); - WireFormat::write(&self.doppler_std, buf); - WireFormat::write(&self.uptime, buf); - WireFormat::write(&self.clock_offset, buf); - WireFormat::write(&self.clock_drift, buf); - WireFormat::write(&self.corr_spacing, buf); - WireFormat::write(&self.acceleration, buf); - WireFormat::write(&self.sync_flags, buf); - WireFormat::write(&self.tow_flags, buf); - WireFormat::write(&self.track_flags, buf); - WireFormat::write(&self.nav_flags, buf); - WireFormat::write(&self.pset_flags, buf); - WireFormat::write(&self.misc_flags, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgTrackingStateDetailedDepA { - sender_id: None, - recv_time: WireFormat::parse_unchecked(buf), - tot: WireFormat::parse_unchecked(buf), - p: WireFormat::parse_unchecked(buf), - p_std: WireFormat::parse_unchecked(buf), - l: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), - lock: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - doppler: WireFormat::parse_unchecked(buf), - doppler_std: WireFormat::parse_unchecked(buf), - uptime: WireFormat::parse_unchecked(buf), - clock_offset: WireFormat::parse_unchecked(buf), - clock_drift: WireFormat::parse_unchecked(buf), - corr_spacing: WireFormat::parse_unchecked(buf), - acceleration: WireFormat::parse_unchecked(buf), - sync_flags: WireFormat::parse_unchecked(buf), - tow_flags: WireFormat::parse_unchecked(buf), - track_flags: WireFormat::parse_unchecked(buf), - nav_flags: WireFormat::parse_unchecked(buf), - pset_flags: WireFormat::parse_unchecked(buf), - misc_flags: WireFormat::parse_unchecked(buf), +pub mod tracking_channel_correlation { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Complex correlation structure + /// + /// Structure containing in-phase and quadrature correlation components. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TrackingChannelCorrelation { + /// In-phase correlation + #[cfg_attr(feature = "serde", serde(rename(serialize = "I")))] + pub i: i16, + /// Quadrature correlation + #[cfg_attr(feature = "serde", serde(rename(serialize = "Q")))] + pub q: i16, + } + + impl WireFormat for TrackingChannelCorrelation { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.i) + WireFormat::len(&self.q) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.i, buf); + WireFormat::write(&self.q, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TrackingChannelCorrelation { + i: WireFormat::parse_unchecked(buf), + q: WireFormat::parse_unchecked(buf), + } } } } -/// Measurement Engine signal tracking channel state -/// -/// Measurement Engine tracking channel state for a specific satellite signal -/// and measured signal power. The mesid field for Glonass can either carry -/// the FCN as 100 + FCN where FCN is in \[-7, +6\] or the Slot ID (from 1 to -/// 28). -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MeasurementState { - /// Measurement Engine GNSS signal being tracked (carries either Glonass FCN - /// or SLOT) - #[cfg_attr(feature = "serde", serde(rename(serialize = "mesid")))] - pub mesid: GnssSignal, - /// Carrier-to-Noise density. Zero implies invalid cn0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, -} +pub mod tracking_channel_correlation_dep { + #![allow(unused_imports)] -impl WireFormat for MeasurementState { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.mesid) + WireFormat::len(&self.cn0) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.mesid, buf); - WireFormat::write(&self.cn0, buf); + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Complex correlation structure + /// + /// Structure containing in-phase and quadrature correlation components. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TrackingChannelCorrelationDep { + /// In-phase correlation + #[cfg_attr(feature = "serde", serde(rename(serialize = "I")))] + pub i: i32, + /// Quadrature correlation + #[cfg_attr(feature = "serde", serde(rename(serialize = "Q")))] + pub q: i32, } - fn parse_unchecked(buf: &mut B) -> Self { - MeasurementState { - mesid: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), + + impl WireFormat for TrackingChannelCorrelationDep { + const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.i) + WireFormat::len(&self.q) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.i, buf); + WireFormat::write(&self.q, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TrackingChannelCorrelationDep { + i: WireFormat::parse_unchecked(buf), + q: WireFormat::parse_unchecked(buf), + } } } } -/// Complex correlation structure -/// -/// Structure containing in-phase and quadrature correlation components. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TrackingChannelCorrelation { - /// In-phase correlation - #[cfg_attr(feature = "serde", serde(rename(serialize = "I")))] - pub i: i16, - /// Quadrature correlation - #[cfg_attr(feature = "serde", serde(rename(serialize = "Q")))] - pub q: i16, -} +pub mod tracking_channel_state { + #![allow(unused_imports)] -impl WireFormat for TrackingChannelCorrelation { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.i) + WireFormat::len(&self.q) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.i, buf); - WireFormat::write(&self.q, buf); + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; + + /// Signal tracking channel state + /// + /// Tracking channel state for a specific satellite signal and measured signal + /// power. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TrackingChannelState { + /// GNSS signal being tracked + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignal, + /// Frequency channel number (GLONASS only) + #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] + pub fcn: u8, + /// Carrier-to-Noise density. Zero implies invalid cn0. + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: u8, } - fn parse_unchecked(buf: &mut B) -> Self { - TrackingChannelCorrelation { - i: WireFormat::parse_unchecked(buf), - q: WireFormat::parse_unchecked(buf), + + impl WireFormat for TrackingChannelState { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.sid) + WireFormat::len(&self.fcn) + WireFormat::len(&self.cn0) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.fcn, buf); + WireFormat::write(&self.cn0, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TrackingChannelState { + sid: WireFormat::parse_unchecked(buf), + fcn: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + } } } } -/// Complex correlation structure -/// -/// Structure containing in-phase and quadrature correlation components. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TrackingChannelCorrelationDep { - /// In-phase correlation - #[cfg_attr(feature = "serde", serde(rename(serialize = "I")))] - pub i: i32, - /// Quadrature correlation - #[cfg_attr(feature = "serde", serde(rename(serialize = "Q")))] - pub q: i32, -} +pub mod tracking_channel_state_dep_a { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl WireFormat for TrackingChannelCorrelationDep { - const MIN_LEN: usize = ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.i) + WireFormat::len(&self.q) + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TrackingChannelStateDepA { + /// Status of tracking channel + #[cfg_attr(feature = "serde", serde(rename(serialize = "state")))] + pub state: u8, + /// PRN-1 being tracked + #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] + pub prn: u8, + /// Carrier-to-noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: f32, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.i, buf); - WireFormat::write(&self.q, buf); + + impl TrackingChannelStateDepA { + /// Gets the [TrackingMode][self::TrackingMode] stored in the `state` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingMode` were added. + pub fn tracking_mode(&self) -> Result { + get_bit_range!(self.state, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingMode][TrackingMode] of the `state` bitfield. + pub fn set_tracking_mode(&mut self, tracking_mode: TrackingMode) { + set_bit_range!(&mut self.state, tracking_mode, u8, u8, 1, 0); + } } - fn parse_unchecked(buf: &mut B) -> Self { - TrackingChannelCorrelationDep { - i: WireFormat::parse_unchecked(buf), - q: WireFormat::parse_unchecked(buf), + + impl WireFormat for TrackingChannelStateDepA { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.state) + WireFormat::len(&self.prn) + WireFormat::len(&self.cn0) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.state, buf); + WireFormat::write(&self.prn, buf); + WireFormat::write(&self.cn0, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TrackingChannelStateDepA { + state: WireFormat::parse_unchecked(buf), + prn: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + } } } -} -/// Signal tracking channel state -/// -/// Tracking channel state for a specific satellite signal and measured signal -/// power. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TrackingChannelState { - /// GNSS signal being tracked - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignal, - /// Frequency channel number (GLONASS only) - #[cfg_attr(feature = "serde", serde(rename(serialize = "fcn")))] - pub fcn: u8, - /// Carrier-to-Noise density. Zero implies invalid cn0. - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: u8, -} + /// Tracking mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingMode { + /// Disabled + Disabled = 0, -impl WireFormat for TrackingChannelState { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.sid) + WireFormat::len(&self.fcn) + WireFormat::len(&self.cn0) + /// Running + Running = 1, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.fcn, buf); - WireFormat::write(&self.cn0, buf); + + impl std::fmt::Display for TrackingMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingMode::Disabled => f.write_str("Disabled"), + TrackingMode::Running => f.write_str("Running"), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - TrackingChannelState { - sid: WireFormat::parse_unchecked(buf), - fcn: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), + + impl TryFrom for TrackingMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingMode::Disabled), + 1 => Ok(TrackingMode::Running), + i => Err(i), + } } } } -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TrackingChannelStateDepA { - /// Status of tracking channel - #[cfg_attr(feature = "serde", serde(rename(serialize = "state")))] - pub state: u8, - /// PRN-1 being tracked - #[cfg_attr(feature = "serde", serde(rename(serialize = "prn")))] - pub prn: u8, - /// Carrier-to-noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: f32, -} +pub mod tracking_channel_state_dep_b { + #![allow(unused_imports)] + + use super::*; + use crate::messages::gnss::*; + use crate::messages::lib::*; -impl WireFormat for TrackingChannelStateDepA { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.state) + WireFormat::len(&self.prn) + WireFormat::len(&self.cn0) + /// Deprecated + /// + /// Deprecated. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct TrackingChannelStateDepB { + /// Status of tracking channel + #[cfg_attr(feature = "serde", serde(rename(serialize = "state")))] + pub state: u8, + /// GNSS signal being tracked + #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] + pub sid: GnssSignalDep, + /// Carrier-to-noise density + #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] + pub cn0: f32, } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.state, buf); - WireFormat::write(&self.prn, buf); - WireFormat::write(&self.cn0, buf); + + impl TrackingChannelStateDepB { + /// Gets the [TrackingMode][self::TrackingMode] stored in the `state` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TrackingMode` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TrackingMode` were added. + pub fn tracking_mode(&self) -> Result { + get_bit_range!(self.state, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TrackingMode][TrackingMode] of the `state` bitfield. + pub fn set_tracking_mode(&mut self, tracking_mode: TrackingMode) { + set_bit_range!(&mut self.state, tracking_mode, u8, u8, 1, 0); + } } - fn parse_unchecked(buf: &mut B) -> Self { - TrackingChannelStateDepA { - state: WireFormat::parse_unchecked(buf), - prn: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), + + impl WireFormat for TrackingChannelStateDepB { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.state) + WireFormat::len(&self.sid) + WireFormat::len(&self.cn0) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.state, buf); + WireFormat::write(&self.sid, buf); + WireFormat::write(&self.cn0, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + TrackingChannelStateDepB { + state: WireFormat::parse_unchecked(buf), + sid: WireFormat::parse_unchecked(buf), + cn0: WireFormat::parse_unchecked(buf), + } } } -} -/// Deprecated -/// -/// Deprecated. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct TrackingChannelStateDepB { - /// Status of tracking channel - #[cfg_attr(feature = "serde", serde(rename(serialize = "state")))] - pub state: u8, - /// GNSS signal being tracked - #[cfg_attr(feature = "serde", serde(rename(serialize = "sid")))] - pub sid: GnssSignalDep, - /// Carrier-to-noise density - #[cfg_attr(feature = "serde", serde(rename(serialize = "cn0")))] - pub cn0: f32, -} + /// Tracking mode + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TrackingMode { + /// Disabled + Disabled = 0, + + /// Running + Running = 1, + } + + impl std::fmt::Display for TrackingMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TrackingMode::Disabled => f.write_str("Disabled"), + TrackingMode::Running => f.write_str("Running"), + } + } + } -impl WireFormat for TrackingChannelStateDepB { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.state) + WireFormat::len(&self.sid) + WireFormat::len(&self.cn0) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.state, buf); - WireFormat::write(&self.sid, buf); - WireFormat::write(&self.cn0, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - TrackingChannelStateDepB { - state: WireFormat::parse_unchecked(buf), - sid: WireFormat::parse_unchecked(buf), - cn0: WireFormat::parse_unchecked(buf), + impl TryFrom for TrackingMode { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TrackingMode::Disabled), + 1 => Ok(TrackingMode::Running), + i => Err(i), + } } } } diff --git a/rust/sbp/src/messages/user.rs b/rust/sbp/src/messages/user.rs index fb1c07506e..ee72a4ba8d 100644 --- a/rust/sbp/src/messages/user.rs +++ b/rust/sbp/src/messages/user.rs @@ -13,70 +13,76 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Messages reserved for use by the user. +pub use msg_user_data::MsgUserData; -use super::lib::*; +pub mod msg_user_data { + #![allow(unused_imports)] -/// User data -/// -/// This message can contain any application specific user data up to a -/// maximum length of 255 bytes per message. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgUserData { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// User data payload - #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] - pub contents: Vec, -} - -impl ConcreteMessage for MsgUserData { - const MESSAGE_TYPE: u16 = 2048; - const MESSAGE_NAME: &'static str = "MSG_USER_DATA"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgUserData { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME - } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE - } - fn sender_id(&self) -> Option { - self.sender_id + /// User data + /// + /// This message can contain any application specific user data up to a + /// maximum length of 255 bytes per message. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgUserData { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// User data payload + #[cfg_attr(feature = "serde", serde(rename(serialize = "contents")))] + pub contents: Vec, } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); - } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl ConcreteMessage for MsgUserData { + const MESSAGE_TYPE: u16 = 2048; + const MESSAGE_NAME: &'static str = "MSG_USER_DATA"; } -} -impl TryFrom for MsgUserData { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgUserData(m) => Ok(m), - _ => Err(TryFromSbpError), + impl SbpMessage for MsgUserData { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN } } -} -impl WireFormat for MsgUserData { - const MIN_LEN: usize = as WireFormat>::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.contents) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.contents, buf); + impl TryFrom for MsgUserData { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgUserData(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - fn parse_unchecked(buf: &mut B) -> Self { - MsgUserData { - sender_id: None, - contents: WireFormat::parse_unchecked(buf), + + impl WireFormat for MsgUserData { + const MIN_LEN: usize = as WireFormat>::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.contents) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.contents, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgUserData { + sender_id: None, + contents: WireFormat::parse_unchecked(buf), + } } } } diff --git a/rust/sbp/src/messages/vehicle.rs b/rust/sbp/src/messages/vehicle.rs index 3ab5628a51..e1ebd14fb3 100644 --- a/rust/sbp/src/messages/vehicle.rs +++ b/rust/sbp/src/messages/vehicle.rs @@ -13,212 +13,499 @@ // with generate.py. Please do not hand edit! //****************************************************************************/ //! Messages from a vehicle. +pub use msg_odometry::MsgOdometry; +pub use msg_wheeltick::MsgWheeltick; -use super::lib::*; - -/// Vehicle forward (x-axis) velocity -/// -/// Message representing the x component of vehicle velocity in the user frame -/// at the odometry reference point(s) specified by the user. The offset for -/// the odometry reference point and the definition and origin of the user -/// frame are defined through the device settings interface. There are 4 -/// possible user-defined sources of this message which are labeled -/// arbitrarily source 0 through 3. If using "processor time" time tags, the -/// receiving end will expect a `MSG_GNSS_TIME_OFFSET` when a PVT fix becomes -/// available to synchronise odometry measurements with GNSS. Processor time -/// shall roll over to zero after one week. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgOdometry { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Time field representing either milliseconds in the GPS Week or local CPU - /// time from the producing system in milliseconds. See the tow_source flag - /// for the exact source of this timestamp. - #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] - pub tow: u32, - /// The signed forward component of vehicle velocity. - #[cfg_attr(feature = "serde", serde(rename(serialize = "velocity")))] - pub velocity: i32, - /// Status flags - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, -} +pub mod msg_odometry { + #![allow(unused_imports)] -impl ConcreteMessage for MsgOdometry { - const MESSAGE_TYPE: u16 = 2307; - const MESSAGE_NAME: &'static str = "MSG_ODOMETRY"; -} + use super::*; + use crate::messages::lib::*; -impl SbpMessage for MsgOdometry { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME + /// Vehicle forward (x-axis) velocity + /// + /// Message representing the x component of vehicle velocity in the user frame + /// at the odometry reference point(s) specified by the user. The offset for + /// the odometry reference point and the definition and origin of the user + /// frame are defined through the device settings interface. There are 4 + /// possible user-defined sources of this message which are labeled + /// arbitrarily source 0 through 3. If using "processor time" time tags, the + /// receiving end will expect a `MSG_GNSS_TIME_OFFSET` when a PVT fix becomes + /// available to synchronise odometry measurements with GNSS. Processor time + /// shall roll over to zero after one week. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgOdometry { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Time field representing either milliseconds in the GPS Week or local CPU + /// time from the producing system in milliseconds. See the tow_source flag + /// for the exact source of this timestamp. + #[cfg_attr(feature = "serde", serde(rename(serialize = "tow")))] + pub tow: u32, + /// The signed forward component of vehicle velocity. + #[cfg_attr(feature = "serde", serde(rename(serialize = "velocity")))] + pub velocity: i32, + /// Status flags + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgOdometry { + /// Gets the [VehicleMetadata][self::VehicleMetadata] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VehicleMetadata` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VehicleMetadata` were added. + pub fn vehicle_metadata(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 6, 5).try_into() + } + + /// Set the bitrange corresponding to the [VehicleMetadata][VehicleMetadata] of the `flags` bitfield. + pub fn set_vehicle_metadata(&mut self, vehicle_metadata: VehicleMetadata) { + set_bit_range!(&mut self.flags, vehicle_metadata, u8, u8, 6, 5); + } + + /// Gets the [VelocitySource][self::VelocitySource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VelocitySource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VelocitySource` were added. + pub fn velocity_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 4, 3).try_into() + } + + /// Set the bitrange corresponding to the [VelocitySource][VelocitySource] of the `flags` bitfield. + pub fn set_velocity_source(&mut self, velocity_source: VelocitySource) { + set_bit_range!(&mut self.flags, velocity_source, u8, u8, 4, 3); + } + + /// Gets the [TimeSource][self::TimeSource] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeSource` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeSource` were added. + pub fn time_source(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 2, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeSource][TimeSource] of the `flags` bitfield. + pub fn set_time_source(&mut self, time_source: TimeSource) { + set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgOdometry { + const MESSAGE_TYPE: u16 = 2307; + const MESSAGE_NAME: &'static str = "MSG_ODOMETRY"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgOdometry { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + let tow_s = (self.tow as f64) / 1000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgOdometry { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgOdometry(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - let tow_s = (self.tow as f64) / 1000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) + + impl WireFormat for MsgOdometry { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.tow) + + WireFormat::len(&self.velocity) + + WireFormat::len(&self.flags) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.tow, buf); + WireFormat::write(&self.velocity, buf); + WireFormat::write(&self.flags, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgOdometry { + sender_id: None, + tow: WireFormat::parse_unchecked(buf), + velocity: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + } + } } -} -impl TryFrom for MsgOdometry { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgOdometry(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Vehicle Metadata + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VehicleMetadata { + /// Unavailable + Unavailable = 0, + + /// Forward + Forward = 1, + + /// Reverse + Reverse = 2, + + /// Park + Park = 3, + } + + impl std::fmt::Display for VehicleMetadata { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VehicleMetadata::Unavailable => f.write_str("Unavailable"), + VehicleMetadata::Forward => f.write_str("Forward"), + VehicleMetadata::Reverse => f.write_str("Reverse"), + VehicleMetadata::Park => f.write_str("Park"), + } } } -} -impl WireFormat for MsgOdometry { - const MIN_LEN: usize = - ::MIN_LEN + ::MIN_LEN + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.tow) + WireFormat::len(&self.velocity) + WireFormat::len(&self.flags) + impl TryFrom for VehicleMetadata { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VehicleMetadata::Unavailable), + 1 => Ok(VehicleMetadata::Forward), + 2 => Ok(VehicleMetadata::Reverse), + 3 => Ok(VehicleMetadata::Park), + i => Err(i), + } + } } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.tow, buf); - WireFormat::write(&self.velocity, buf); - WireFormat::write(&self.flags, buf); + + /// Velocity Source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VelocitySource { + /// Source 0 + Source0 = 0, + + /// Source 1 + Source1 = 1, + + /// Source 2 + Source2 = 2, + + /// Source 3 + Source3 = 3, } - fn parse_unchecked(buf: &mut B) -> Self { - MsgOdometry { - sender_id: None, - tow: WireFormat::parse_unchecked(buf), - velocity: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), + + impl std::fmt::Display for VelocitySource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VelocitySource::Source0 => f.write_str("Source 0"), + VelocitySource::Source1 => f.write_str("Source 1"), + VelocitySource::Source2 => f.write_str("Source 2"), + VelocitySource::Source3 => f.write_str("Source 3"), + } } } -} -/// Accumulated wheeltick count message -/// -/// Message containing the accumulated distance travelled by a wheel located -/// at an odometry reference point defined by the user. The offset for the -/// odometry reference point and the definition and origin of the user frame -/// are defined through the device settings interface. The source of this -/// message is identified by the source field, which is an integer ranging -/// from 0 to 255. The timestamp associated with this message should represent -/// the time when the accumulated tick count reached the value given by the -/// contents of this message as accurately as possible. If using "local CPU -/// time" time tags, the receiving end will expect a `MSG_GNSS_TIME_OFFSET` -/// when a PVT fix becomes available to synchronise wheeltick measurements -/// with GNSS. Local CPU time shall roll over to zero after one week. -/// -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[derive(Debug, Clone)] -pub struct MsgWheeltick { - /// The message sender_id - #[cfg_attr(feature = "serde", serde(skip_serializing))] - pub sender_id: Option, - /// Time field representing either microseconds since the last PPS, - /// microseconds in the GPS Week or local CPU time from the producing system - /// in microseconds. See the synch_type field for the exact meaning of this - /// timestamp. - #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] - pub time: u64, - /// Field indicating the type of timestamp contained in the time field. - #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] - pub flags: u8, - /// ID of the sensor producing this message - #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] - pub source: u8, - /// Free-running counter of the accumulated distance for this sensor. The - /// counter should be incrementing if travelling into one direction and - /// decrementing when travelling in the opposite direction. - #[cfg_attr(feature = "serde", serde(rename(serialize = "ticks")))] - pub ticks: i32, -} + impl TryFrom for VelocitySource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VelocitySource::Source0), + 1 => Ok(VelocitySource::Source1), + 2 => Ok(VelocitySource::Source2), + 3 => Ok(VelocitySource::Source3), + i => Err(i), + } + } + } + + /// Time source + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeSource { + /// None (invalid) + None = 0, + + /// GPS Solution (ms in week) + GpsSolution = 1, -impl ConcreteMessage for MsgWheeltick { - const MESSAGE_TYPE: u16 = 2308; - const MESSAGE_NAME: &'static str = "MSG_WHEELTICK"; + /// Processor Time + ProcessorTime = 2, + } + + impl std::fmt::Display for TimeSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeSource::None => f.write_str("None (invalid)"), + TimeSource::GpsSolution => f.write_str("GPS Solution (ms in week)"), + TimeSource::ProcessorTime => f.write_str("Processor Time"), + } + } + } + + impl TryFrom for TimeSource { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeSource::None), + 1 => Ok(TimeSource::GpsSolution), + 2 => Ok(TimeSource::ProcessorTime), + i => Err(i), + } + } + } } -impl SbpMessage for MsgWheeltick { - fn message_name(&self) -> &'static str { - ::MESSAGE_NAME +pub mod msg_wheeltick { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Accumulated wheeltick count message + /// + /// Message containing the accumulated distance travelled by a wheel located + /// at an odometry reference point defined by the user. The offset for the + /// odometry reference point and the definition and origin of the user frame + /// are defined through the device settings interface. The source of this + /// message is identified by the source field, which is an integer ranging + /// from 0 to 255. The timestamp associated with this message should represent + /// the time when the accumulated tick count reached the value given by the + /// contents of this message as accurately as possible. If using "local CPU + /// time" time tags, the receiving end will expect a `MSG_GNSS_TIME_OFFSET` + /// when a PVT fix becomes available to synchronise wheeltick measurements + /// with GNSS. Local CPU time shall roll over to zero after one week. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[derive(Debug, Clone)] + pub struct MsgWheeltick { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing))] + pub sender_id: Option, + /// Time field representing either microseconds since the last PPS, + /// microseconds in the GPS Week or local CPU time from the producing system + /// in microseconds. See the synch_type field for the exact meaning of this + /// timestamp. + #[cfg_attr(feature = "serde", serde(rename(serialize = "time")))] + pub time: u64, + /// Field indicating the type of timestamp contained in the time field. + #[cfg_attr(feature = "serde", serde(rename(serialize = "flags")))] + pub flags: u8, + /// ID of the sensor producing this message + #[cfg_attr(feature = "serde", serde(rename(serialize = "source")))] + pub source: u8, + /// Free-running counter of the accumulated distance for this sensor. The + /// counter should be incrementing if travelling into one direction and + /// decrementing when travelling in the opposite direction. + #[cfg_attr(feature = "serde", serde(rename(serialize = "ticks")))] + pub ticks: i32, } - fn message_type(&self) -> u16 { - ::MESSAGE_TYPE + + impl MsgWheeltick { + /// Gets the [VehicleMetadata][self::VehicleMetadata] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `VehicleMetadata` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `VehicleMetadata` were added. + pub fn vehicle_metadata(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 3, 2).try_into() + } + + /// Set the bitrange corresponding to the [VehicleMetadata][VehicleMetadata] of the `flags` bitfield. + pub fn set_vehicle_metadata(&mut self, vehicle_metadata: VehicleMetadata) { + set_bit_range!(&mut self.flags, vehicle_metadata, u8, u8, 3, 2); + } + + /// Gets the [SynchronizationType][self::SynchronizationType] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `SynchronizationType` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `SynchronizationType` were added. + pub fn synchronization_type(&self) -> Result { + get_bit_range!(self.flags, u8, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [SynchronizationType][SynchronizationType] of the `flags` bitfield. + pub fn set_synchronization_type(&mut self, synchronization_type: SynchronizationType) { + set_bit_range!(&mut self.flags, synchronization_type, u8, u8, 1, 0); + } } - fn sender_id(&self) -> Option { - self.sender_id + + impl ConcreteMessage for MsgWheeltick { + const MESSAGE_TYPE: u16 = 2308; + const MESSAGE_NAME: &'static str = "MSG_WHEELTICK"; } - fn set_sender_id(&mut self, new_id: u16) { - self.sender_id = Some(new_id); + + impl SbpMessage for MsgWheeltick { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> u16 { + ::MESSAGE_TYPE + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + #[cfg(feature = "swiftnav")] + fn gps_time(&self) -> Option> { + // only consider wheelticks with synchronization type value "microsec in GPS week" + if self.flags != 1 { + return None; + } + let tow_s = (self.time as f64) / 1000000.0; + let gps_time = match time::GpsTime::new(0, tow_s) { + Ok(gps_time) => gps_time.tow(), + Err(e) => return Some(Err(e.into())), + }; + Some(Ok(time::MessageTime::Rover(gps_time.into()))) + } } - fn encoded_len(&self) -> usize { - WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + + impl TryFrom for MsgWheeltick { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgWheeltick(m) => Ok(m), + _ => Err(TryFromSbpError), + } + } } - #[cfg(feature = "swiftnav")] - fn gps_time(&self) -> Option> { - // only consider wheelticks with synchronization type value "microsec in GPS week" - if self.flags != 1 { - return None; + + impl WireFormat for MsgWheeltick { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.source) + + WireFormat::len(&self.ticks) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.source, buf); + WireFormat::write(&self.ticks, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgWheeltick { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + source: WireFormat::parse_unchecked(buf), + ticks: WireFormat::parse_unchecked(buf), + } } - let tow_s = (self.time as f64) / 1000000.0; - let gps_time = match time::GpsTime::new(0, tow_s) { - Ok(gps_time) => gps_time.tow(), - Err(e) => return Some(Err(e.into())), - }; - Some(Ok(time::MessageTime::Rover(gps_time.into()))) } -} -impl TryFrom for MsgWheeltick { - type Error = TryFromSbpError; - fn try_from(msg: Sbp) -> Result { - match msg { - Sbp::MsgWheeltick(m) => Ok(m), - _ => Err(TryFromSbpError), + /// Vehicle Metadata + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum VehicleMetadata { + /// Unavailable + Unavailable = 0, + + /// Forward + Forward = 1, + + /// Reverse + Reverse = 2, + + /// Park + Park = 3, + } + + impl std::fmt::Display for VehicleMetadata { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VehicleMetadata::Unavailable => f.write_str("Unavailable"), + VehicleMetadata::Forward => f.write_str("Forward"), + VehicleMetadata::Reverse => f.write_str("Reverse"), + VehicleMetadata::Park => f.write_str("Park"), + } + } + } + + impl TryFrom for VehicleMetadata { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(VehicleMetadata::Unavailable), + 1 => Ok(VehicleMetadata::Forward), + 2 => Ok(VehicleMetadata::Reverse), + 3 => Ok(VehicleMetadata::Park), + i => Err(i), + } + } + } + + /// Synchronization type + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum SynchronizationType { + /// microseconds since last PPS + MicrosecondsSinceLastPps = 0, + + /// microseconds in GPS week + MicrosecondsInGpsWeek = 1, + + /// local CPU time in nominal microseconds + LocalCpuTimeInNominalMicroseconds = 2, + } + + impl std::fmt::Display for SynchronizationType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SynchronizationType::MicrosecondsSinceLastPps => { + f.write_str("microseconds since last PPS") + } + SynchronizationType::MicrosecondsInGpsWeek => { + f.write_str("microseconds in GPS week") + } + SynchronizationType::LocalCpuTimeInNominalMicroseconds => { + f.write_str("local CPU time in nominal microseconds") + } + } } } -} -impl WireFormat for MsgWheeltick { - const MIN_LEN: usize = ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN - + ::MIN_LEN; - fn len(&self) -> usize { - WireFormat::len(&self.time) - + WireFormat::len(&self.flags) - + WireFormat::len(&self.source) - + WireFormat::len(&self.ticks) - } - fn write(&self, buf: &mut B) { - WireFormat::write(&self.time, buf); - WireFormat::write(&self.flags, buf); - WireFormat::write(&self.source, buf); - WireFormat::write(&self.ticks, buf); - } - fn parse_unchecked(buf: &mut B) -> Self { - MsgWheeltick { - sender_id: None, - time: WireFormat::parse_unchecked(buf), - flags: WireFormat::parse_unchecked(buf), - source: WireFormat::parse_unchecked(buf), - ticks: WireFormat::parse_unchecked(buf), + impl TryFrom for SynchronizationType { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(SynchronizationType::MicrosecondsSinceLastPps), + 1 => Ok(SynchronizationType::MicrosecondsInGpsWeek), + 2 => Ok(SynchronizationType::LocalCpuTimeInNominalMicroseconds), + i => Err(i), + } } } } diff --git a/rust/sbp2json/Cargo.toml b/rust/sbp2json/Cargo.toml index f6a16f9ff4..db666f7749 100644 --- a/rust/sbp2json/Cargo.toml +++ b/rust/sbp2json/Cargo.toml @@ -7,7 +7,7 @@ [package] name = "sbp2json" -version = "4.1.3-unreleased" +version = "4.1.4-alpha" description = "Rust native implementation of SBP (Swift Binary Protocol) to JSON conversion tools" authors = ["Swift Navigation "] edition = "2018" diff --git a/spec/yaml/swiftnav/sbp/system.yaml b/spec/yaml/swiftnav/sbp/system.yaml index 61e075275a..98e8e5d942 100644 --- a/spec/yaml/swiftnav/sbp/system.yaml +++ b/spec/yaml/swiftnav/sbp/system.yaml @@ -201,7 +201,7 @@ definitions: type: u16 desc: SBP protocol version fields: - - 8-16: + - 8-15: desc: SBP major protocol version number - 0-7: desc: SBP minor protocol version number