use std::{
fmt,
mem,
};
use bitflags::bitflags;
pub use dtv_property_cmd::*;
pub use fe_type::*;
pub use fecap_scale_params::*;
use crate::error::{
Error,
Result,
};
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FeCaps: u32 {
const CAN_INVERSION_AUTO = 0x1;
const CAN_FEC_1_2 = 0x2;
const CAN_FEC_2_3 = 0x4;
const CAN_FEC_3_4 = 0x8;
const CAN_FEC_4_5 = 0x10;
const CAN_FEC_5_6 = 0x20;
const CAN_FEC_6_7 = 0x40;
const CAN_FEC_7_8 = 0x80;
const CAN_FEC_8_9 = 0x100;
const CAN_FEC_AUTO = 0x200;
const CAN_QPSK = 0x400;
const CAN_QAM_16 = 0x800;
const CAN_QAM_32 = 0x1000;
const CAN_QAM_64 = 0x2000;
const CAN_QAM_128 = 0x4000;
const CAN_QAM_256 = 0x8000;
const CAN_QAM_AUTO = 0x10000;
const CAN_TRANSMISSION_MODE_AUTO = 0x20000;
const CAN_BANDWIDTH_AUTO = 0x40000;
const CAN_GUARD_INTERVAL_AUTO = 0x80000;
const CAN_HIERARCHY_AUTO = 0x100000;
const CAN_8VSB = 0x200000;
const CAN_16VSB = 0x400000;
const HAS_EXTENDED_CAPS = 0x800000;
const CAN_MULTISTREAM = 0x4000000;
const CAN_TURBO_FEC = 0x8000000;
const CAN_2G_MODULATION = 0x10000000;
const NEEDS_BENDING = 0x20000000;
const CAN_RECOVER = 0x40000000;
const CAN_MUTE_TS = 0x80000000;
}
}
impl FeCaps {
pub const IS_STUPID: Self = Self::empty();
}
mod fe_type {
pub const FE_QPSK: u32 = 0;
pub const FE_QAM: u32 = 1;
pub const FE_OFDM: u32 = 2;
pub const FE_ATSC: u32 = 3;
}
#[repr(C)]
#[derive(Debug)]
pub struct FeInfo {
pub name: [u8; 128],
pub fe_type: u32,
pub frequency_min: u32,
pub frequency_max: u32,
pub frequency_stepsize: u32,
pub frequency_tolerance: u32,
pub symbol_rate_min: u32,
pub symbol_rate_max: u32,
pub symbol_rate_tolerance: u32,
pub notifier_delay: u32,
pub caps: u32,
}
impl Default for FeInfo {
#[inline]
fn default() -> Self {
unsafe { mem::zeroed::<Self>() }
}
}
impl FeInfo {
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut FeInfo {
self as *mut _
}
}
#[repr(C)]
#[derive(Debug)]
pub struct DiseqcMasterCmd {
pub msg: [u8; 6],
pub len: u8,
}
impl Default for DiseqcMasterCmd {
#[inline]
fn default() -> Self {
unsafe { mem::zeroed::<Self>() }
}
}
#[repr(C)]
#[derive(Debug)]
pub struct DiseqcSlaveReply {
pub msg: [u8; 4],
pub len: u8,
pub timeout: u32,
}
impl Default for DiseqcSlaveReply {
#[inline]
fn default() -> Self {
unsafe { mem::zeroed::<Self>() }
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FeStatusFlags: u32 {
const HAS_SIGNAL = 0x01;
const HAS_CARRIER = 0x02;
const HAS_VITERBI = 0x04;
const HAS_SYNC = 0x08;
const HAS_LOCK = 0x10;
const TIMEDOUT = 0x20;
const REINIT = 0x40;
}
}
impl FeStatusFlags {
pub const NONE: Self = Self::empty();
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecVoltage {
V13 = 0,
V18 = 1,
Off = 2,
}
impl TryFrom<u32> for SecVoltage {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(SecVoltage::V13),
1 => Ok(SecVoltage::V18),
2 => Ok(SecVoltage::Off),
_ => Err(Error::InvalidData(format!(
"invalid SecVoltage value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecTone {
On = 0,
Off = 1,
}
impl TryFrom<u32> for SecTone {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(SecTone::On),
1 => Ok(SecTone::Off),
_ => Err(Error::InvalidData(format!(
"invalid SecTone value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecMiniCmd {
A = 0,
B = 1,
}
impl TryFrom<u32> for SecMiniCmd {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(SecMiniCmd::A),
1 => Ok(SecMiniCmd::B),
_ => Err(Error::InvalidData(format!(
"invalid SecMiniCmd value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Inversion {
Off = 0,
On = 1,
Auto = 2,
}
impl TryFrom<u32> for Inversion {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(Inversion::Off),
1 => Ok(Inversion::On),
2 => Ok(Inversion::Auto),
_ => Err(Error::InvalidData(format!(
"invalid Inversion value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Pilot {
On = 0,
Off = 1,
Auto = 2,
}
impl TryFrom<u32> for Pilot {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(Pilot::On),
1 => Ok(Pilot::Off),
2 => Ok(Pilot::Auto),
_ => Err(Error::InvalidData(format!(
"invalid Pilot value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Rolloff {
R35 = 0,
R20 = 1,
R25 = 2,
Auto = 3,
R15 = 4,
R10 = 5,
R5 = 6,
}
impl TryFrom<u32> for Rolloff {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(Rolloff::R35),
1 => Ok(Rolloff::R20),
2 => Ok(Rolloff::R25),
3 => Ok(Rolloff::Auto),
4 => Ok(Rolloff::R15),
5 => Ok(Rolloff::R10),
6 => Ok(Rolloff::R5),
_ => Err(Error::InvalidData(format!(
"invalid Rolloff value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GuardInterval {
Gi1_32 = 0,
Gi1_16 = 1,
Gi1_8 = 2,
Gi1_4 = 3,
Auto = 4,
Gi1_128 = 5,
Gi19_128 = 6,
Gi19_256 = 7,
Pn420 = 8,
Pn595 = 9,
Pn945 = 10,
}
impl TryFrom<u32> for GuardInterval {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(GuardInterval::Gi1_32),
1 => Ok(GuardInterval::Gi1_16),
2 => Ok(GuardInterval::Gi1_8),
3 => Ok(GuardInterval::Gi1_4),
4 => Ok(GuardInterval::Auto),
5 => Ok(GuardInterval::Gi1_128),
6 => Ok(GuardInterval::Gi19_128),
7 => Ok(GuardInterval::Gi19_256),
8 => Ok(GuardInterval::Pn420),
9 => Ok(GuardInterval::Pn595),
10 => Ok(GuardInterval::Pn945),
_ => Err(Error::InvalidData(format!(
"invalid GuardInterval value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransmitMode {
Tm2K = 0,
Tm8K = 1,
Auto = 2,
Tm4K = 3,
Tm1K = 4,
Tm16K = 5,
Tm32K = 6,
C1 = 7,
C3780 = 8,
}
impl TryFrom<u32> for TransmitMode {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(TransmitMode::Tm2K),
1 => Ok(TransmitMode::Tm8K),
2 => Ok(TransmitMode::Auto),
3 => Ok(TransmitMode::Tm4K),
4 => Ok(TransmitMode::Tm1K),
5 => Ok(TransmitMode::Tm16K),
6 => Ok(TransmitMode::Tm32K),
7 => Ok(TransmitMode::C1),
8 => Ok(TransmitMode::C3780),
_ => Err(Error::InvalidData(format!(
"invalid TransmitMode value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Hierarchy {
None = 0,
H1 = 1,
H2 = 2,
H4 = 3,
Auto = 4,
}
impl TryFrom<u32> for Hierarchy {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(Hierarchy::None),
1 => Ok(Hierarchy::H1),
2 => Ok(Hierarchy::H2),
3 => Ok(Hierarchy::H4),
4 => Ok(Hierarchy::Auto),
_ => Err(Error::InvalidData(format!(
"invalid Hierarchy value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Interleaving {
None = 0,
Auto = 1,
I240 = 2,
I720 = 3,
}
impl TryFrom<u32> for Interleaving {
type Error = Error;
#[inline]
fn try_from(value: u32) -> Result<Self> {
match value {
0 => Ok(Interleaving::None),
1 => Ok(Interleaving::Auto),
2 => Ok(Interleaving::I240),
3 => Ok(Interleaving::I720),
_ => Err(Error::InvalidData(format!(
"invalid Interleaving value: {}",
value
))),
}
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeliverySystem {
Undefined = 0,
DvbcAnnexA = 1,
DvbcAnnexB = 2,
Dvbt = 3,
Dss = 4,
Dvbs = 5,
Dvbs2 = 6,
Dvbh = 7,
Isdbt = 8,
Isdbs = 9,
Isdbc = 10,
Atsc = 11,
Atscmh = 12,
Dtmb = 13,
Cmmb = 14,
Dab = 15,
Dvbt2 = 16,
Turbo = 17,
DvbcAnnexC = 18,
Dvbc2 = 19,
}
impl DeliverySystem {
#[inline]
pub fn as_u32(self) -> u32 {
self as u32
}
}
impl TryFrom<u32> for DeliverySystem {
type Error = Error;
fn try_from(value: u32) -> Result<Self> {
let result = match value {
0 => DeliverySystem::Undefined,
1 => DeliverySystem::DvbcAnnexA,
2 => DeliverySystem::DvbcAnnexB,
3 => DeliverySystem::Dvbt,
4 => DeliverySystem::Dss,
5 => DeliverySystem::Dvbs,
6 => DeliverySystem::Dvbs2,
7 => DeliverySystem::Dvbh,
8 => DeliverySystem::Isdbt,
9 => DeliverySystem::Isdbs,
10 => DeliverySystem::Isdbc,
11 => DeliverySystem::Atsc,
12 => DeliverySystem::Atscmh,
13 => DeliverySystem::Dtmb,
14 => DeliverySystem::Cmmb,
15 => DeliverySystem::Dab,
16 => DeliverySystem::Dvbt2,
17 => DeliverySystem::Turbo,
18 => DeliverySystem::DvbcAnnexC,
19 => DeliverySystem::Dvbc2,
_ => {
return Err(Error::InvalidData(format!(
"invalid DeliverySystem value: {}",
value
)));
}
};
Ok(result)
}
}
impl fmt::Display for DeliverySystem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let v = match self {
DeliverySystem::Undefined => "none",
DeliverySystem::DvbcAnnexA => "dvb-c",
DeliverySystem::DvbcAnnexB => "dvb-c/b",
DeliverySystem::Dvbt => "dvb-t",
DeliverySystem::Dss => "dss",
DeliverySystem::Dvbs => "dvb-s",
DeliverySystem::Dvbs2 => "dvb-s2",
DeliverySystem::Dvbh => "dvb-h",
DeliverySystem::Isdbt => "isdb-t",
DeliverySystem::Isdbs => "isdb-s",
DeliverySystem::Isdbc => "isdb-c",
DeliverySystem::Atsc => "atsc",
DeliverySystem::Atscmh => "atsc-m/h",
DeliverySystem::Dtmb => "dtmb",
DeliverySystem::Cmmb => "cmmb",
DeliverySystem::Dab => "dab",
DeliverySystem::Dvbt2 => "dvb-t2",
DeliverySystem::Turbo => "dvb-s/turbo",
DeliverySystem::DvbcAnnexC => "dvb-c/c",
DeliverySystem::Dvbc2 => "dvb-c2",
};
write!(f, "{}", v)
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Modulation {
Qpsk = 0,
Qam16 = 1,
Qam32 = 2,
Qam64 = 3,
Qam128 = 4,
Qam256 = 5,
QamAuto = 6,
Vsb8 = 7,
Vsb16 = 8,
Psk8 = 9,
Apsk16 = 10,
Apsk32 = 11,
Dqpsk = 12,
Qam4Nr = 13,
Apsk64 = 14,
Apsk128 = 15,
Apsk256 = 16,
}
impl Modulation {
#[inline]
pub fn as_u32(self) -> u32 {
self as u32
}
}
impl TryFrom<u32> for Modulation {
type Error = Error;
fn try_from(value: u32) -> Result<Self> {
let result = match value {
0 => Modulation::Qpsk,
1 => Modulation::Qam16,
2 => Modulation::Qam32,
3 => Modulation::Qam64,
4 => Modulation::Qam128,
5 => Modulation::Qam256,
6 => Modulation::QamAuto,
7 => Modulation::Vsb8,
8 => Modulation::Vsb16,
9 => Modulation::Psk8,
10 => Modulation::Apsk16,
11 => Modulation::Apsk32,
12 => Modulation::Dqpsk,
13 => Modulation::Qam4Nr,
14 => Modulation::Apsk64,
15 => Modulation::Apsk128,
16 => Modulation::Apsk256,
_ => {
return Err(Error::InvalidData(format!(
"invalid Modulation value: {}",
value
)));
}
};
Ok(result)
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Fec {
None = 0,
Fec1_2 = 1,
Fec2_3 = 2,
Fec3_4 = 3,
Fec4_5 = 4,
Fec5_6 = 5,
Fec6_7 = 6,
Fec7_8 = 7,
Fec8_9 = 8,
Auto = 9,
Fec3_5 = 10,
Fec9_10 = 11,
Fec2_5 = 12,
Fec1_4 = 13,
Fec1_3 = 14,
}
impl Fec {
#[inline]
pub fn as_u32(self) -> u32 {
self as u32
}
}
impl TryFrom<u32> for Fec {
type Error = Error;
fn try_from(value: u32) -> Result<Self> {
let result = match value {
0 => Fec::None,
1 => Fec::Fec1_2,
2 => Fec::Fec2_3,
3 => Fec::Fec3_4,
4 => Fec::Fec4_5,
5 => Fec::Fec5_6,
6 => Fec::Fec6_7,
7 => Fec::Fec7_8,
8 => Fec::Fec8_9,
9 => Fec::Auto,
10 => Fec::Fec3_5,
11 => Fec::Fec9_10,
12 => Fec::Fec2_5,
13 => Fec::Fec1_4,
14 => Fec::Fec1_3,
_ => {
return Err(Error::InvalidData(format!(
"invalid code rate value: {}",
value
)));
}
};
Ok(result)
}
}
mod fecap_scale_params {
pub const FE_SCALE_NOT_AVAILABLE: u8 = 0;
pub const FE_SCALE_DECIBEL: u8 = 1;
pub const FE_SCALE_RELATIVE: u8 = 2;
pub const FE_SCALE_COUNTER: u8 = 3;
}
#[repr(C, packed)]
#[derive(Copy, Clone)]
pub struct DtvStats {
pub scale: u8, pub value: i64,
}
impl fmt::Debug for DtvStats {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = f.debug_struct("DtvStats");
const FIELD_SCALE: &str = "scale";
const FIELD_VALUE: &str = "value";
match self.scale {
FE_SCALE_NOT_AVAILABLE => {
s.field(FIELD_SCALE, &"FE_SCALE_NOT_AVAILABLE");
s.field(FIELD_VALUE, &"not available");
}
FE_SCALE_DECIBEL => {
s.field(FIELD_SCALE, &"FE_SCALE_DECIBEL");
s.field(FIELD_VALUE, &{ (self.value as f64) / 1000.0 });
}
FE_SCALE_RELATIVE => {
s.field(FIELD_SCALE, &"FE_SCALE_RELATIVE");
s.field(FIELD_VALUE, &{ self.value as u64 });
}
FE_SCALE_COUNTER => {
s.field(FIELD_SCALE, &"FE_SCALE_COUNTER");
s.field(FIELD_VALUE, &{ self.value as u64 });
}
_ => {
s.field(FIELD_SCALE, &{ self.scale });
s.field(FIELD_VALUE, &"invalid scale format");
}
};
s.finish()
}
}
pub const MAX_DTV_STATS: usize = 4;
#[repr(C, packed)]
#[derive(Copy, Clone)]
pub struct DtvFrontendStats {
pub len: u8,
pub stat: [DtvStats; MAX_DTV_STATS],
}
impl fmt::Debug for DtvFrontendStats {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let len = ::std::cmp::min(self.len as usize, self.stat.len());
f.debug_list().entries(self.stat[0 .. len].iter()).finish()
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct DtvPropertyBuffer {
pub data: [u8; 32],
pub len: u32,
__reserved_1: [u32; 3],
__reserved_2: usize,
}
#[repr(C)]
pub union DtvPropertyData {
pub data: u32,
pub st: DtvFrontendStats,
pub buffer: DtvPropertyBuffer,
__align: [u8; 56],
}
mod dtv_property_cmd {
pub const DTV_UNDEFINED: u32 = 0;
pub const DTV_TUNE: u32 = 1;
pub const DTV_CLEAR: u32 = 2;
pub const DTV_FREQUENCY: u32 = 3;
pub const DTV_MODULATION: u32 = 4;
pub const DTV_BANDWIDTH_HZ: u32 = 5;
pub const DTV_INVERSION: u32 = 6;
pub const DTV_DISEQC_MASTER: u32 = 7;
pub const DTV_SYMBOL_RATE: u32 = 8;
pub const DTV_INNER_FEC: u32 = 9;
pub const DTV_VOLTAGE: u32 = 10;
pub const DTV_TONE: u32 = 11;
pub const DTV_PILOT: u32 = 12;
pub const DTV_ROLLOFF: u32 = 13;
pub const DTV_DISEQC_SLAVE_REPLY: u32 = 14;
pub const DTV_FE_CAPABILITY_COUNT: u32 = 15;
pub const DTV_FE_CAPABILITY: u32 = 16;
pub const DTV_DELIVERY_SYSTEM: u32 = 17;
pub const DTV_ISDBT_PARTIAL_RECEPTION: u32 = 18;
pub const DTV_ISDBT_SOUND_BROADCASTING: u32 = 19;
pub const DTV_ISDBT_SB_SUBCHANNEL_ID: u32 = 20;
pub const DTV_ISDBT_SB_SEGMENT_IDX: u32 = 21;
pub const DTV_ISDBT_SB_SEGMENT_COUNT: u32 = 22;
pub const DTV_ISDBT_LAYERA_FEC: u32 = 23;
pub const DTV_ISDBT_LAYERA_MODULATION: u32 = 24;
pub const DTV_ISDBT_LAYERA_SEGMENT_COUNT: u32 = 25;
pub const DTV_ISDBT_LAYERA_TIME_INTERLEAVING: u32 = 26;
pub const DTV_ISDBT_LAYERB_FEC: u32 = 27;
pub const DTV_ISDBT_LAYERB_MODULATION: u32 = 28;
pub const DTV_ISDBT_LAYERB_SEGMENT_COUNT: u32 = 29;
pub const DTV_ISDBT_LAYERB_TIME_INTERLEAVING: u32 = 30;
pub const DTV_ISDBT_LAYERC_FEC: u32 = 31;
pub const DTV_ISDBT_LAYERC_MODULATION: u32 = 32;
pub const DTV_ISDBT_LAYERC_SEGMENT_COUNT: u32 = 33;
pub const DTV_ISDBT_LAYERC_TIME_INTERLEAVING: u32 = 34;
pub const DTV_API_VERSION: u32 = 35;
pub const DTV_CODE_RATE_HP: u32 = 36;
pub const DTV_CODE_RATE_LP: u32 = 37;
pub const DTV_GUARD_INTERVAL: u32 = 38;
pub const DTV_TRANSMISSION_MODE: u32 = 39;
pub const DTV_HIERARCHY: u32 = 40;
pub const DTV_ISDBT_LAYER_ENABLED: u32 = 41;
pub const DTV_STREAM_ID: u32 = 42;
pub const DTV_DVBT2_PLP_ID_LEGACY: u32 = 43;
pub const DTV_ENUM_DELSYS: u32 = 44;
pub const DTV_ATSCMH_FIC_VER: u32 = 45;
pub const DTV_ATSCMH_PARADE_ID: u32 = 46;
pub const DTV_ATSCMH_NOG: u32 = 47;
pub const DTV_ATSCMH_TNOG: u32 = 48;
pub const DTV_ATSCMH_SGN: u32 = 49;
pub const DTV_ATSCMH_PRC: u32 = 50;
pub const DTV_ATSCMH_RS_FRAME_MODE: u32 = 51;
pub const DTV_ATSCMH_RS_FRAME_ENSEMBLE: u32 = 52;
pub const DTV_ATSCMH_RS_CODE_MODE_PRI: u32 = 53;
pub const DTV_ATSCMH_RS_CODE_MODE_SEC: u32 = 54;
pub const DTV_ATSCMH_SCCC_BLOCK_MODE: u32 = 55;
pub const DTV_ATSCMH_SCCC_CODE_MODE_A: u32 = 56;
pub const DTV_ATSCMH_SCCC_CODE_MODE_B: u32 = 57;
pub const DTV_ATSCMH_SCCC_CODE_MODE_C: u32 = 58;
pub const DTV_ATSCMH_SCCC_CODE_MODE_D: u32 = 59;
pub const DTV_INTERLEAVING: u32 = 60;
pub const DTV_LNA: u32 = 61;
pub const DTV_STAT_SIGNAL_STRENGTH: u32 = 62;
pub const DTV_STAT_CNR: u32 = 63;
pub const DTV_STAT_PRE_ERROR_BIT_COUNT: u32 = 64;
pub const DTV_STAT_PRE_TOTAL_BIT_COUNT: u32 = 65;
pub const DTV_STAT_POST_ERROR_BIT_COUNT: u32 = 66;
pub const DTV_STAT_POST_TOTAL_BIT_COUNT: u32 = 67;
pub const DTV_STAT_ERROR_BLOCK_COUNT: u32 = 68;
pub const DTV_STAT_TOTAL_BLOCK_COUNT: u32 = 69;
pub const DTV_SCRAMBLING_SEQUENCE_INDEX: u32 = 70;
pub const DTV_INPUT: u32 = 71;
}
#[repr(C, packed)]
pub struct DtvPropertyRaw {
pub cmd: u32,
__reserved_1: [u32; 3],
pub u: DtvPropertyData,
pub result: i32,
}
impl fmt::Debug for DtvPropertyRaw {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = f.debug_struct("DtvPropertyRaw");
const FIELD_CMD: &str = "cmd";
const FIELD_DATA: &str = "data";
const FIELD_STATS: &str = "stats";
match self.cmd {
DTV_FREQUENCY => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_FREQUENCY");
s.field(FIELD_DATA, &data);
}
DTV_MODULATION => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_MODULATION");
s.field(FIELD_DATA, &data);
}
DTV_BANDWIDTH_HZ => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_BANDWIDTH_HZ");
s.field(FIELD_DATA, &data);
}
DTV_INVERSION => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_INVERSION");
s.field(FIELD_DATA, &data);
}
DTV_SYMBOL_RATE => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_SYMBOL_RATE");
s.field(FIELD_DATA, &data);
}
DTV_INNER_FEC => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_INNER_FEC");
s.field(FIELD_DATA, &data);
}
DTV_PILOT => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_PILOT");
s.field(FIELD_DATA, &data);
}
DTV_ROLLOFF => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_ROLLOFF");
s.field(FIELD_DATA, &data);
}
DTV_DELIVERY_SYSTEM => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_DELIVERY_SYSTEM");
s.field(FIELD_DATA, &data);
}
DTV_API_VERSION => {
let data = self.data();
s.field(FIELD_CMD, &"DTV_API_VERSION");
s.field(FIELD_DATA, &data);
}
DTV_STAT_SIGNAL_STRENGTH => {
s.field(FIELD_CMD, &"DTV_STAT_SIGNAL_STRENGTH");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_CNR => {
s.field(FIELD_CMD, &"DTV_STAT_CNR");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_PRE_ERROR_BIT_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_PRE_ERROR_BIT_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_PRE_TOTAL_BIT_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_PRE_TOTAL_BIT_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_POST_ERROR_BIT_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_POST_ERROR_BIT_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_POST_TOTAL_BIT_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_POST_TOTAL_BIT_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_ERROR_BLOCK_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_ERROR_BLOCK_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
DTV_STAT_TOTAL_BLOCK_COUNT => {
s.field(FIELD_CMD, &"DTV_STAT_TOTAL_BLOCK_COUNT");
s.field(FIELD_STATS, unsafe { &self.u.st });
}
_ => {}
}
s.field("result", &{ self.result });
s.finish()
}
}
impl DtvPropertyRaw {
pub fn new(cmd: u32, data: u32) -> Self {
Self {
cmd,
__reserved_1: [0, 0, 0],
u: DtvPropertyData { data },
result: 0,
}
}
pub(crate) fn data(&self) -> u32 {
let ptr = std::ptr::addr_of!(self.u).cast::<u32>();
unsafe { ptr.read_unaligned() }
}
pub(crate) fn stats(&self) -> DtvFrontendStats {
let ptr = std::ptr::addr_of!(self.u).cast::<DtvFrontendStats>();
unsafe { ptr.read_unaligned() }
}
pub(crate) fn set_stats(&mut self, stats: DtvFrontendStats) {
let ptr = std::ptr::addr_of_mut!(self.u).cast::<DtvFrontendStats>();
unsafe { ptr.write_unaligned(stats) };
}
pub(crate) fn stat(&self, index: usize) -> Option<DtvStats> {
let stats = self.stats();
if index < usize::from(stats.len) {
Some(stats.stat[index])
} else {
None
}
}
}
pub const DTV_MAX_COMMAND: u32 = DTV_INPUT;
pub const DTV_IOCTL_MAX_MSGS: usize = 64;
#[repr(C)]
#[derive(Debug)]
pub struct FeParameters {
pub frequency: u32,
pub inversion: u32,
__reserved_1: [u8; 28],
}
pub const FE_MAX_EVENT: usize = 8;
#[repr(C)]
#[derive(Debug)]
pub struct FeEvent {
pub status: u32,
pub parameters: FeParameters,
}
impl Default for FeEvent {
#[inline]
fn default() -> Self {
unsafe { mem::zeroed::<Self>() }
}
}
impl FeEvent {
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut FeEvent {
self as *mut _
}
}