#[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_packet_recv;
const PATCH_ENTRY_SIZE: usize = 16;
#[ubx_packet_recv]
#[ubx(class = 0x0a, id = 0x27, max_payload_len = 516)] struct MonPatch {
version: u16,
n_entries: u16,
#[ubx(map_type = MonPatchEntryIter, may_fail,
from = MonPatchEntryIter::new,
is_valid = MonPatchEntryIter::is_valid)]
patches: [u8; 0],
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct MonPatchEntry {
pub patch_info: MonPatchInfo,
pub comparator_number: u32,
pub patch_address: u32,
pub patch_data: u32,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct MonPatchInfo(u32);
impl MonPatchInfo {
pub fn activated(&self) -> bool {
self.0 & 0x01 != 0
}
pub fn location(&self) -> u8 {
((self.0 >> 1) & 0x03) as u8
}
pub fn raw(&self) -> u32 {
self.0
}
}
impl From<u32> for MonPatchInfo {
fn from(value: u32) -> Self {
Self(value)
}
}
#[derive(Debug, Clone)]
pub struct MonPatchEntryIter<'a> {
data: &'a [u8],
offset: usize,
}
impl<'a> MonPatchEntryIter<'a> {
fn new(data: &'a [u8]) -> Self {
Self { data, offset: 0 }
}
#[allow(dead_code, reason = "Used by ubx_packet_recv macro for validation")]
fn is_valid(payload: &[u8]) -> bool {
payload.len().is_multiple_of(PATCH_ENTRY_SIZE)
}
}
impl core::iter::Iterator for MonPatchEntryIter<'_> {
type Item = MonPatchEntry;
fn next(&mut self) -> Option<Self::Item> {
let chunk = self.data.get(self.offset..self.offset + PATCH_ENTRY_SIZE)?;
let entry = MonPatchEntry {
patch_info: MonPatchInfo(u32::from_le_bytes(chunk[0..4].try_into().ok()?)),
comparator_number: u32::from_le_bytes(chunk[4..8].try_into().ok()?),
patch_address: u32::from_le_bytes(chunk[8..12].try_into().ok()?),
patch_data: u32::from_le_bytes(chunk[12..16].try_into().ok()?),
};
self.offset += PATCH_ENTRY_SIZE;
Some(entry)
}
}