use crate::binrw_util;
use alloc::vec::Vec;
use binrw::binrw;
use bitflags::bitflags;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExtError: u8 {
const SIS = 0x01;
const DIFF_CORR = 0x02;
const EXT_SENSOR = 0x04;
const SETUP = 0x08;
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RxState: u32 {
const ACTIVE_ANTENNA = 1 << 1;
const EXT_FREQ = 1 << 2;
const EXT_TIME = 1 << 3;
const WN_SET = 1 << 4;
const TOW_SET = 1 << 5;
const FINE_TIME = 1 << 6;
const INTERNAL_DISK_ACTIVITY = 1 << 7;
const INTERNAL_DISK_FULL = 1 << 8;
const INTERNAL_DISK_MOUNTED = 1 << 9;
const INT_ANT = 1 << 10;
const REFOUT_LOCKED = 1 << 11;
const EXTERNAL_DISK_ACTIVITY = 1 << 13;
const EXTERNAL_DISK_FULL = 1 << 14;
const EXTERNAL_DISK_MOUNTED = 1 << 15;
const PPS_IN_CAL = 1 << 16;
const DIFFCORR_IN = 1 << 17;
const INTERNET = 1 << 18;
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RxError: u32 {
const SOFTWARE = 1 << 3;
const WATCHDOG = 1 << 4;
const ANTENNA = 1 << 5;
const CONGESTION = 1 << 6;
const MISSED_EVENT = 1 << 8;
const CPU_OVERLOAD = 1 << 9;
const INVALID_CONFIG = 1 << 10;
const OUT_OF_GEOFENCE = 1 << 11;
}
}
#[binrw]
#[derive(Clone, Debug)]
pub struct ReceiverStatus {
#[br(map = binrw_util::map_u4)]
#[bw(map = binrw_util::unmap_u4)]
pub tow: Option<u32>,
#[br(map = binrw_util::map_u2)]
#[bw(map = binrw_util::unmap_u2)]
pub wnc: Option<u16>,
#[br(map = binrw_util::map_u1)]
#[bw(map = binrw_util::unmap_u1)]
pub cpu_load: Option<u8>,
#[br(map = |x: u8| ExtError::from_bits_truncate(x))]
#[bw(map = |x: &ExtError| x.bits())]
pub ext_error: ExtError,
pub up_time: u32,
#[br(map = |x: u32| RxState::from_bits_truncate(x))]
#[bw(map = |x: &RxState| x.bits())]
pub rx_state: RxState,
#[br(map = |x: u32| RxError::from_bits_truncate(x))]
#[bw(map = |x: &RxError| x.bits())]
pub rx_error: RxError,
pub n: u8,
pub sb_length: u8,
pub cmd_count: u8,
pub temperature: u8,
#[br(args { count: usize::from(n), inner: (usize::from(sb_length),) }, map = binrw_util::unwrap_subblocks)]
#[bw(args_raw = (usize::from(*sb_length),), map = binrw_util::wrap_subblocks)]
pub agc_state: Vec<AGCState>,
#[br(parse_with = binrw::helpers::until_eof)]
pub padding: Vec<u8>,
}
#[binrw]
#[derive(Clone, Debug)]
pub struct AGCState {
pub frontend_id: u8,
#[br(map = binrw_util::map_i1)]
#[bw(map = binrw_util::unmap_i1)]
pub gain: Option<i8>,
pub sample_var: u8,
pub blanking_stat: u8,
}
impl AGCState {
pub fn frontend_code(&self) -> u8 {
self.frontend_id & 0x1F
}
pub fn antenna_id(&self) -> u8 {
(self.frontend_id >> 5) & 0x07
}
}
impl ReceiverStatus {
pub fn software_error(&self) -> bool {
self.rx_error.contains(RxError::SOFTWARE)
}
pub fn watchdog_error(&self) -> bool {
self.rx_error.contains(RxError::WATCHDOG)
}
pub fn antenna_error(&self) -> bool {
self.rx_error.contains(RxError::ANTENNA)
}
pub fn congestion_error(&self) -> bool {
self.rx_error.contains(RxError::CONGESTION)
}
pub fn cpu_overload_error(&self) -> bool {
self.rx_error.contains(RxError::CPU_OVERLOAD)
}
pub fn sis_error(&self) -> bool {
self.ext_error.contains(ExtError::SIS)
}
pub fn diff_corr_error(&self) -> bool {
self.ext_error.contains(ExtError::DIFF_CORR)
}
pub fn ext_sensor_error(&self) -> bool {
self.ext_error.contains(ExtError::EXT_SENSOR)
}
pub fn setup_error(&self) -> bool {
self.ext_error.contains(ExtError::SETUP)
}
}