#![cfg(any(
feature = "ubx_proto27",
feature = "ubx_proto31",
feature = "ubx_proto33",
))]
#[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 = 0x0a, id = 0x38, max_payload_len = 1028)] pub struct MonRf {
version: u8,
n_blocks: u8,
reserved0: [u8; 2],
#[ubx(map_type = RfBlockIter, may_fail,
from = RfBlockIter::new,
is_valid = RfBlockIter::is_valid)]
blocks: [u8; 0],
}
#[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 AntennaStatus {
Init = 0,
DontKnow = 1,
Ok = 2,
Short = 3,
Open = 4,
}
#[ubx_extend]
#[ubx(from, rest_reserved)]
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum AntennaPowerStatus {
Off = 0,
On = 1,
DontKnow = 2,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Flags {
pub jamming_state: JammingState,
}
impl From<u8> for Flags {
fn from(value: u8) -> Self {
Self {
jamming_state: JammingState::from(value & 0x03),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct RfBlock {
pub block_id: u8,
pub flags: Flags,
pub ant_status: AntennaStatus,
pub ant_power: AntennaPowerStatus,
pub post_status: u32,
pub reserved1: [u8; 4],
pub noise_per_ms: u16,
pub agc_cnt: u16,
pub jam_ind: u8,
pub ofs_i: i8,
pub mag_i: u8,
pub ofs_q: i8,
pub mag_q: u8,
pub reserved2: [u8; 3],
}
#[derive(Debug, Clone)]
pub struct RfBlockIter<'a> {
data: &'a [u8],
offset: usize,
}
impl<'a> RfBlockIter<'a> {
fn new(data: &'a [u8]) -> Self {
Self { data, offset: 0 }
}
fn is_valid(payload: &[u8]) -> bool {
payload.len().is_multiple_of(24)
}
}
impl core::iter::Iterator for RfBlockIter<'_> {
type Item = RfBlock;
fn next(&mut self) -> Option<Self::Item> {
let chunk = self.data.get(self.offset..self.offset + 24)?;
let block = RfBlock {
block_id: chunk[0],
flags: Flags::from(chunk[1]),
ant_status: AntennaStatus::from(chunk[2]),
ant_power: AntennaPowerStatus::from(chunk[3]),
post_status: u32::from_le_bytes(chunk[4..8].try_into().ok()?),
reserved1: chunk[8..12].try_into().ok()?,
noise_per_ms: u16::from_le_bytes(chunk[12..14].try_into().ok()?),
agc_cnt: u16::from_le_bytes(chunk[14..16].try_into().ok()?),
jam_ind: chunk[16],
ofs_i: chunk[17] as i8,
mag_i: chunk[18],
ofs_q: chunk[19] as i8,
mag_q: chunk[20],
reserved2: chunk[21..24].try_into().ok()?,
};
self.offset += 24;
Some(block)
}
}