#[cfg(feature = "serde")]
use super::SerializeUbxPacketFields;
#[cfg(feature = "serde")]
use crate::serde::ser::SerializeMap;
#[allow(unused_imports, reason = "It is only unused in some feature sets")]
use crate::FieldIter;
use crate::{error::ParserError, UbxPacketMeta};
use ublox_derive::{ubx_extend, ubx_packet_recv};
#[ubx_packet_recv]
#[ubx(class = 0x27, id = 0x09, max_payload_len = 1028)] struct SecSig {
version: u8,
#[ubx(map_type = SecSigFlags)]
sig_sec_flags: u8,
reserved0: u8,
jam_num_cent_freqs: u8,
#[ubx(map_type = SecSigJamStateCentFreqIter, may_fail,
from = SecSigJamStateCentFreqIter::new,
is_valid = SecSigJamStateCentFreqIter::is_valid)]
jam_state_cent_freqs: [u8; 0],
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct SecSigJamStateCentFreq {
pub cent_freq_khz: u32,
pub jammed: bool,
}
impl From<u32> for SecSigJamStateCentFreq {
fn from(value: u32) -> Self {
Self {
cent_freq_khz: value & 0x00ff_ffff,
jammed: (value & 0x0100_0000) != 0,
}
}
}
#[derive(Debug, Clone)]
pub struct SecSigJamStateCentFreqIter<'d> {
data: &'d [u8],
offset: usize,
}
impl<'d> SecSigJamStateCentFreqIter<'d> {
fn new(data: &'d [u8]) -> Self {
Self { data, offset: 0 }
}
#[allow(
dead_code,
reason = "Used by ubx_packet_recv macro for validation, but may appear unused in some feature configurations"
)]
fn is_valid(payload: &[u8]) -> bool {
payload.len().is_multiple_of(4)
}
}
impl core::iter::Iterator for SecSigJamStateCentFreqIter<'_> {
type Item = SecSigJamStateCentFreq;
fn next(&mut self) -> Option<Self::Item> {
let chunk = self.data.get(self.offset..self.offset + 4)?;
let raw = u32::from_le_bytes(chunk.try_into().ok()?);
self.offset += 4;
Some(SecSigJamStateCentFreq::from(raw))
}
}
#[ubx_extend]
#[ubx(from, rest_reserved)]
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum JammingState {
Unknown = 0,
Ok = 1,
Warning = 2,
Critical = 3,
}
#[ubx_extend]
#[ubx(from, rest_reserved)]
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SpoofingState {
Unknown = 0,
Ok = 1,
Indicated = 2,
Multiple = 3,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct SecSigFlags {
pub jam_det_enabled: bool,
pub spf_det_enabled: bool,
pub jamming_state: JammingState,
pub spoofing_state: SpoofingState,
}
impl From<u8> for SecSigFlags {
fn from(value: u8) -> Self {
Self {
jam_det_enabled: (value & 0x01) != 0,
spf_det_enabled: (value & 0x08) != 0,
jamming_state: JammingState::from((value >> 1) & 0x03),
spoofing_state: SpoofingState::from((value >> 4) & 0x07),
}
}
}