pub mod bits;
pub mod cli;
pub mod dsm;
pub mod input;
pub mod mac;
pub mod maclt;
pub mod maclt_data;
pub mod merkle;
pub mod navdata;
pub mod page;
pub mod signature;
pub mod subframe;
pub mod tables;
pub mod tesla;
pub mod ubx;
pub mod verifier;
pub use page::{InavPage, PageError, PAGE_BITS};
pub use subframe::{DsmHeader, MackLayout, NmaHeader, Subframe, SubframeAssembler};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OsnmaStatus {
Authenticated,
Failed,
Unavailable,
}
pub const ADVISORY: &str = "Advisory: this is analysis and monitoring output and not type-approved navigation equipment. The authentication status reported here is not a navigation integrity service and must not be the sole basis for any navigation or safety decision.";
impl OsnmaStatus {
pub fn letter(self) -> char {
match self {
Self::Authenticated => 'A',
Self::Failed => 'F',
Self::Unavailable => 'N',
}
}
}
pub const WEEK_S: u32 = 604_800;
pub fn gst_pack(secs: u32) -> u32 {
(((secs / WEEK_S) & 0xFFF) << 20) | (secs % WEEK_S)
}
pub fn gst_secs(wn: u32, tow: u32) -> u32 {
wn * WEEK_S + tow
}
#[cfg(test)]
mod gst_tests {
use super::*;
#[test]
fn pack_puts_week_above_time_of_week() {
let s = gst_secs(1248, 345_660);
assert_eq!(gst_pack(s), (1248 << 20) | 345_660);
assert_eq!(gst_pack(gst_secs(4097, 5)), (1 << 20) | 5); }
}
pub fn pksos_sentence(overall: OsnmaStatus, sats: &[(String, OsnmaStatus)]) -> String {
let mut body = format!("PKSOS,{}", overall.letter());
for (s, st) in sats {
body.push_str(&format!(",{s}:{}", st.letter()));
}
let cs = body.bytes().fold(0u8, |a, b| a ^ b);
format!("${body}*{cs:02X}")
}
#[cfg(test)]
mod pksos_tests {
use super::*;
#[test]
fn sentence_form_and_checksum() {
let s = pksos_sentence(
OsnmaStatus::Failed,
&[
("E02".into(), OsnmaStatus::Authenticated),
("E05".into(), OsnmaStatus::Failed),
],
);
assert!(s.starts_with("$PKSOS,F,E02:A,E05:F*"));
let (body, cs) = s[1..].split_once('*').unwrap();
assert_eq!(
u8::from_str_radix(cs, 16).unwrap(),
body.bytes().fold(0, |a, b| a ^ b)
);
assert_eq!(
pksos_sentence(OsnmaStatus::Unavailable, &[])
.split('*')
.next(),
Some("$PKSOS,N")
);
}
}