mirror of
https://github.com/danog/libdvb.git
synced 2024-11-30 04:19:00 +01:00
fe status reading with fallback to DVBv3 API
This commit is contained in:
parent
8198ccca69
commit
8a558d7470
@ -23,7 +23,7 @@ fn check_frontend(path: &Path) -> Result<()> {
|
|||||||
|
|
||||||
let mut status = FeStatus::default();
|
let mut status = FeStatus::default();
|
||||||
status.read(&fe)?;
|
status.read(&fe)?;
|
||||||
println!("{}", &status);
|
println!("Status: {}", &status);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,6 @@ impl FeDevice {
|
|||||||
pub fn get_event(&self, event: &mut FeEvent) -> Result<()> {
|
pub fn get_event(&self, event: &mut FeEvent) -> Result<()> {
|
||||||
// FE_GET_EVENT
|
// FE_GET_EVENT
|
||||||
ioctl_read!(#[inline] ioctl_call, b'o', 78, FeEvent);
|
ioctl_read!(#[inline] ioctl_call, b'o', 78, FeEvent);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
ioctl_call(self.as_raw_fd(), event as *mut _)
|
ioctl_call(self.as_raw_fd(), event as *mut _)
|
||||||
}.context("FE: get event")?;
|
}.context("FE: get event")?;
|
||||||
@ -323,6 +322,79 @@ impl FeDevice {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns frontend status
|
||||||
|
/// - [`FE_NONE`]
|
||||||
|
/// - [`FE_HAS_SIGNAL`]
|
||||||
|
/// - [`FE_HAS_CARRIER`]
|
||||||
|
/// - [`FE_HAS_VITERBI`]
|
||||||
|
/// - [`FE_HAS_SYNC`]
|
||||||
|
/// - [`FE_HAS_LOCK`]
|
||||||
|
/// - [`FE_TIMEDOUT`]
|
||||||
|
/// - [`FE_REINIT`]
|
||||||
|
pub fn read_status(&self) -> Result<u32> {
|
||||||
|
let mut result: u32 = FE_NONE;
|
||||||
|
|
||||||
|
// FE_READ_STATUS
|
||||||
|
ioctl_read!(#[inline] ioctl_call, b'o', 69, u32);
|
||||||
|
unsafe {
|
||||||
|
ioctl_call(self.as_raw_fd(), &mut result as *mut _)
|
||||||
|
}.context("FE: read status")?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads and returns a signal strength relative value (DVBv3 API)
|
||||||
|
pub fn read_signal_strength(&self) -> Result<u16> {
|
||||||
|
let mut result: u16 = 0;
|
||||||
|
|
||||||
|
// FE_READ_SIGNAL_STRENGTH
|
||||||
|
ioctl_read!(#[inline] ioctl_call, b'o', 71, u16);
|
||||||
|
unsafe {
|
||||||
|
ioctl_call(self.as_raw_fd(), &mut result as *mut _)
|
||||||
|
}.context("FE: read signal strength")?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads and returns a signal-to-noise ratio, relative value (DVBv3 API)
|
||||||
|
pub fn read_snr(&self) -> Result<u16> {
|
||||||
|
let mut result: u16 = 0;
|
||||||
|
|
||||||
|
// FE_READ_SNR
|
||||||
|
ioctl_read!(#[inline] ioctl_call, b'o', 72, u16);
|
||||||
|
unsafe {
|
||||||
|
ioctl_call(self.as_raw_fd(), &mut result as *mut _)
|
||||||
|
}.context("FE: read snr")?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads and returns a bit error counter (DVBv3 API)
|
||||||
|
pub fn read_ber(&self) -> Result<u32> {
|
||||||
|
let mut result: u32 = 0;
|
||||||
|
|
||||||
|
// FE_READ_BER
|
||||||
|
ioctl_read!(#[inline] ioctl_call, b'o', 70, u32);
|
||||||
|
unsafe {
|
||||||
|
ioctl_call(self.as_raw_fd(), &mut result as *mut _)
|
||||||
|
}.context("FE: read ber")?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads and returns an uncorrected blocks counter (DVBv3 API)
|
||||||
|
pub fn read_unc(&self) -> Result<u32> {
|
||||||
|
let mut result: u32 = 0;
|
||||||
|
|
||||||
|
// FE_READ_UNCORRECTED_BLOCKS
|
||||||
|
ioctl_read!(#[inline] ioctl_call, b'o', 73, u32);
|
||||||
|
unsafe {
|
||||||
|
ioctl_call(self.as_raw_fd(), &mut result as *mut _)
|
||||||
|
}.context("FE: read uncorrected blocks")?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns on/off generation of the continuous 22kHz tone
|
/// Turns on/off generation of the continuous 22kHz tone
|
||||||
///
|
///
|
||||||
/// allowed `value`'s:
|
/// allowed `value`'s:
|
||||||
|
352
src/fe/status.rs
352
src/fe/status.rs
@ -1,17 +1,9 @@
|
|||||||
use {
|
use {
|
||||||
std::{
|
std::{
|
||||||
fmt,
|
fmt,
|
||||||
os::unix::io::AsRawFd,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
anyhow::{
|
anyhow::Result,
|
||||||
Context,
|
|
||||||
Result,
|
|
||||||
},
|
|
||||||
|
|
||||||
nix::{
|
|
||||||
ioctl_read,
|
|
||||||
},
|
|
||||||
|
|
||||||
super::{
|
super::{
|
||||||
FeDevice,
|
FeDevice,
|
||||||
@ -27,7 +19,7 @@ pub struct FeStatus {
|
|||||||
status: u32,
|
status: u32,
|
||||||
|
|
||||||
/// properties
|
/// properties
|
||||||
props: [DtvProperty; 4],
|
props: [DtvProperty; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -36,14 +28,18 @@ impl Default for FeStatus {
|
|||||||
FeStatus {
|
FeStatus {
|
||||||
status: 0,
|
status: 0,
|
||||||
props: [
|
props: [
|
||||||
// 0: signal level
|
// 0: delivery system
|
||||||
|
DtvProperty::new(DTV_DELIVERY_SYSTEM, FE_NONE),
|
||||||
|
// 1: signal level
|
||||||
DtvProperty::new(DTV_STAT_SIGNAL_STRENGTH, 0),
|
DtvProperty::new(DTV_STAT_SIGNAL_STRENGTH, 0),
|
||||||
// 1: signal-to-noise ratio
|
// 2: signal-to-noise ratio
|
||||||
DtvProperty::new(DTV_STAT_CNR, 0),
|
DtvProperty::new(DTV_STAT_CNR, 0),
|
||||||
// 2: ber - number of bit errors
|
// 3: ber - number of bit errors
|
||||||
DtvProperty::new(DTV_STAT_PRE_ERROR_BIT_COUNT, 0),
|
DtvProperty::new(DTV_STAT_PRE_ERROR_BIT_COUNT, 0),
|
||||||
// 3: unc - number of block errors
|
// 4: unc - number of block errors
|
||||||
DtvProperty::new(DTV_STAT_ERROR_BLOCK_COUNT, 0),
|
DtvProperty::new(DTV_STAT_ERROR_BLOCK_COUNT, 0),
|
||||||
|
// 5: modulation
|
||||||
|
DtvProperty::new(DTV_MODULATION, QPSK),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,69 +48,80 @@ impl Default for FeStatus {
|
|||||||
|
|
||||||
/// Returns an object that implements `Display` for different verbosity levels
|
/// Returns an object that implements `Display` for different verbosity levels
|
||||||
///
|
///
|
||||||
|
/// Tuner is turned off:
|
||||||
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
/// Status:SCVYL S:-38.56dBm (59%) Q:14.57dB (70%) BER:0 UNC:0
|
/// OFF
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Status:
|
/// Tuner acquiring signal but has no lock:
|
||||||
/// - S - Signal
|
///
|
||||||
/// - C - Carrier
|
/// ```text
|
||||||
/// - V - FEC
|
/// NO-LOCK 0x01 | Signal -38.56dBm (59%)
|
||||||
/// - Y - Sync
|
/// NO-LOCK 0x03 | Signal -38.56dBm (59%) | Quality 5.32dB (25%)
|
||||||
/// - L - Lock
|
/// ```
|
||||||
|
///
|
||||||
|
/// Hex number after `NO-LOCK` this is tuner status bit flags:
|
||||||
|
/// - 0x01 - has signal
|
||||||
|
/// - 0x02 - has carrier
|
||||||
|
/// - 0x04 - has viterbi
|
||||||
|
/// - 0x08 - has sync
|
||||||
|
/// - 0x10 - has lock
|
||||||
|
/// - 0x20 - timed-out
|
||||||
|
/// - 0x40 - re-init
|
||||||
|
///
|
||||||
|
/// Tuner has lock
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// LOCK dvb-s2 | Signal -38.56dBm (59%) | Quality 14.57dB (70%) | BER:0 | UNC:0
|
||||||
|
/// ```
|
||||||
impl fmt::Display for FeStatus {
|
impl fmt::Display for FeStatus {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Status:")?;
|
|
||||||
|
|
||||||
if self.status == FE_NONE {
|
if self.status == FE_NONE {
|
||||||
write!(f, "OFF")?;
|
write!(f, "OFF")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
const STATUS_MAP: &[char] = &['S', 'C', 'V', 'Y', 'L'];
|
if self.status & FE_HAS_LOCK != 0 {
|
||||||
for (i, s) in STATUS_MAP.iter().enumerate() {
|
write!(f, "LOCK {}", DeliverySystemDisplay(self.get_delivery_system()))?;
|
||||||
let c = if self.status & (1 << i) != 0 { *s } else { '_' };
|
} else {
|
||||||
write!(f, "{}", c)?;
|
write!(f, "NO-LOCK 0x{:02X}", self.status)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.status & FE_HAS_SIGNAL == 0 {
|
if self.status & FE_HAS_SIGNAL == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, " Signal:")?;
|
write!(
|
||||||
if let Some(s) = self.get_signal_level() {
|
f,
|
||||||
// TODO: config for lo/hi
|
" | Signal {:.02}dBm ({}%)",
|
||||||
let lo: f64 = -85.0;
|
self.get_signal_strength_decibel().unwrap_or(0.0),
|
||||||
let hi: f64 = -6.0;
|
self.get_signal_strength().unwrap_or(0)
|
||||||
let relative = 100.0 - (s - hi) * 100.0 / (lo - hi);
|
)?;
|
||||||
write!(f, "{:.02}dBm ({:.0}%)", s, relative)?;
|
|
||||||
} else {
|
|
||||||
write!(f, "-")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.status & FE_HAS_CARRIER == 0 {
|
if self.status & FE_HAS_CARRIER == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, " Quality:")?;
|
write!(
|
||||||
if let Some(q) = self.get_signal_noise_ratio() {
|
f,
|
||||||
write!(f, "{:.02}dB", q)?;
|
" | Quality {:.02}dB ({}%)",
|
||||||
} else {
|
self.get_snr_decibel().unwrap_or(0.0),
|
||||||
write!(f, "-")?;
|
self.get_snr().unwrap_or(0)
|
||||||
}
|
)?;
|
||||||
|
|
||||||
if self.status & FE_HAS_LOCK == 0 {
|
if self.status & FE_HAS_LOCK == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, " BER:")?;
|
write!(f, " | BER:")?;
|
||||||
if let Some(ber) = self.get_ber() {
|
if let Some(ber) = self.get_ber() {
|
||||||
write!(f, "{}", ber)?;
|
write!(f, "{}", ber)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "-")?;
|
write!(f, "-")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, " UNC:")?;
|
write!(f, " | UNC:")?;
|
||||||
if let Some(unc) = self.get_unc() {
|
if let Some(unc) = self.get_unc() {
|
||||||
write!(f, "{}", unc)?;
|
write!(f, "{}", unc)?;
|
||||||
} else {
|
} else {
|
||||||
@ -127,64 +134,241 @@ impl fmt::Display for FeStatus {
|
|||||||
|
|
||||||
|
|
||||||
impl FeStatus {
|
impl FeStatus {
|
||||||
fn get_stats_decibel(&self, u: usize) -> Option<f64> {
|
/// Returns current delivery system
|
||||||
let stats = self.props.get(u)?;
|
#[inline]
|
||||||
let stats = unsafe { &stats.u.st };
|
pub fn get_delivery_system(&self) -> u32 { unsafe { self.props[0].u.data } }
|
||||||
|
|
||||||
let len = ::std::cmp::min(stats.len as usize, stats.stat.len());
|
/// Returns current modulation
|
||||||
for s in stats.stat[.. len].iter() {
|
#[inline]
|
||||||
if s.scale == FE_SCALE_DECIBEL {
|
pub fn get_modulation(&self) -> u32 { unsafe { self.props[5].u.data } }
|
||||||
return Some((s.value as f64) / 1000.0);
|
|
||||||
}
|
/// Returns Signal Strength in dBm
|
||||||
|
pub fn get_signal_strength_decibel(&self) -> Option<f64> {
|
||||||
|
let stat = unsafe { &self.props[1].u.st.stat[0] };
|
||||||
|
if stat.scale == FE_SCALE_DECIBEL {
|
||||||
|
Some((stat.value as f64) / 1000.0)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns Signal Level in dBm
|
/// Returns Signal Strength in percentage
|
||||||
#[inline]
|
pub fn get_signal_strength(&self) -> Option<u32> {
|
||||||
pub fn get_signal_level(&self) -> Option<f64> { self.get_stats_decibel(0) }
|
let stat = unsafe { &self.props[1].u.st.stat[1] };
|
||||||
|
if stat.scale == FE_SCALE_RELATIVE {
|
||||||
|
Some(((stat.value & 0xFFFF) * 100 / 65535) as u32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns Signal to noise ratio in dB
|
/// Returns Signal to noise ratio in dB
|
||||||
#[inline]
|
pub fn get_snr_decibel(&self) -> Option<f64> {
|
||||||
pub fn get_signal_noise_ratio(&self) -> Option<f64> { self.get_stats_decibel(1) }
|
let stat = unsafe { &self.props[2].u.st.stat[0] };
|
||||||
|
if stat.scale == FE_SCALE_DECIBEL {
|
||||||
fn get_stats_counter(&self, u: usize) -> Option<u32> {
|
Some((stat.value as f64) / 1000.0)
|
||||||
let stats = self.props.get(u)?;
|
} else {
|
||||||
let stats = unsafe { &stats.u.st };
|
None
|
||||||
if stats.len > 0 {
|
}
|
||||||
let s = &stats.stat[0];
|
}
|
||||||
if s.scale == FE_SCALE_COUNTER {
|
|
||||||
return Some((s.value & 0xFFFF) as u32);
|
/// Returns Signal Strength in percentage
|
||||||
}
|
pub fn get_snr(&self) -> Option<u32> {
|
||||||
|
let stat = unsafe { &self.props[2].u.st.stat[1] };
|
||||||
|
if stat.scale == FE_SCALE_RELATIVE {
|
||||||
|
Some(((stat.value & 0xFFFF) * 100 / 65535) as u32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns BER value if available
|
/// Returns BER value if available
|
||||||
#[inline]
|
pub fn get_ber(&self) -> Option<u32> {
|
||||||
pub fn get_ber(&self) -> Option<u32> { self.get_stats_counter(2) }
|
let stat = unsafe { &self.props[3].u.st.stat[0] };
|
||||||
|
if stat.scale == FE_SCALE_COUNTER {
|
||||||
|
Some((stat.value & 0xFFFF) as u32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns UNC value if available
|
/// Returns UNC value if available
|
||||||
#[inline]
|
pub fn get_unc(&self) -> Option<u32> {
|
||||||
pub fn get_unc(&self) -> Option<u32> { self.get_stats_counter(3) }
|
let stat = unsafe { &self.props[4].u.st.stat[0] };
|
||||||
|
if stat.scale == FE_SCALE_COUNTER {
|
||||||
|
Some((stat.value & 0xFFFF) as u32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads frontend status
|
fn normalize_signal_strength(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
|
let mut stats = unsafe { &mut self.props[1].u.st };
|
||||||
|
|
||||||
|
for i in usize::from(stats.len) .. 2 {
|
||||||
|
stats.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||||
|
stats.stat[i].value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.len = 2;
|
||||||
|
|
||||||
|
if stats.stat[0].scale == FE_SCALE_RELATIVE {
|
||||||
|
stats.stat.swap(0, 1);
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stats.stat[1].scale == FE_SCALE_RELATIVE || (self.status & FE_HAS_SIGNAL) == 0 {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to DVBv3 API
|
||||||
|
|
||||||
|
if let Ok(value) = fe.read_signal_strength() {
|
||||||
|
stats.stat[1].scale = FE_SCALE_RELATIVE;
|
||||||
|
stats.stat[1].value = i64::from(value);
|
||||||
|
} else if stats.stat[0].scale == FE_SCALE_DECIBEL {
|
||||||
|
// TODO: check delivery_system
|
||||||
|
|
||||||
|
let lo: i64 = -85000;
|
||||||
|
let hi: i64 = -6000;
|
||||||
|
|
||||||
|
stats.stat[1].scale = FE_SCALE_RELATIVE;
|
||||||
|
stats.stat[1].value = {
|
||||||
|
if stats.stat[0].value > hi {
|
||||||
|
65545
|
||||||
|
} else if stats.stat[0].value < lo {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
65545 * (lo - stats.stat[0].value) / (lo - hi)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_snr(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
|
let delivery_system = self.get_delivery_system();
|
||||||
|
let modulation = self.get_modulation();
|
||||||
|
|
||||||
|
let mut stats = unsafe { &mut self.props[2].u.st };
|
||||||
|
|
||||||
|
for i in usize::from(stats.len) .. 2 {
|
||||||
|
stats.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||||
|
stats.stat[i].value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.len = 2;
|
||||||
|
|
||||||
|
if stats.stat[0].scale == FE_SCALE_RELATIVE {
|
||||||
|
stats.stat.swap(0, 1);
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
if stats.stat[1].scale == FE_SCALE_RELATIVE || (self.status & FE_HAS_CARRIER) == 0 {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to DVBv3 API
|
||||||
|
|
||||||
|
if let Ok(value) = fe.read_snr() {
|
||||||
|
stats.stat[1].scale = FE_SCALE_RELATIVE;
|
||||||
|
stats.stat[1].value = i64::from(value);
|
||||||
|
} else if stats.stat[0].scale == FE_SCALE_DECIBEL {
|
||||||
|
let maxdb = match delivery_system {
|
||||||
|
SYS_DVBS |
|
||||||
|
SYS_DVBS2 => 15000,
|
||||||
|
|
||||||
|
SYS_DVBC_ANNEX_A |
|
||||||
|
SYS_DVBC_ANNEX_B |
|
||||||
|
SYS_DVBC_ANNEX_C |
|
||||||
|
SYS_DVBC2 => 28000,
|
||||||
|
|
||||||
|
SYS_DVBT |
|
||||||
|
SYS_DVBT2 => 19000,
|
||||||
|
|
||||||
|
SYS_ATSC => {
|
||||||
|
match modulation {
|
||||||
|
VSB_8 | VSB_16 => 19000,
|
||||||
|
_ => 28000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if maxdb != 0 {
|
||||||
|
stats.stat[1].scale = FE_SCALE_RELATIVE;
|
||||||
|
stats.stat[1].value = {
|
||||||
|
if stats.stat[0].value >= maxdb {
|
||||||
|
65535
|
||||||
|
} else if stats.stat[0].value <= 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
65535 * stats.stat[0].value / maxdb
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_ber(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
|
let mut stats = unsafe { &mut self.props[3].u.st };
|
||||||
|
|
||||||
|
if stats.len == 0 || stats.stat[0].scale != FE_SCALE_COUNTER {
|
||||||
|
if let Ok(value) = fe.read_ber() {
|
||||||
|
stats.stat[0].scale = FE_SCALE_COUNTER;
|
||||||
|
stats.stat[0].value = i64::from(value);
|
||||||
|
} else {
|
||||||
|
stats.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||||
|
stats.stat[0].value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_unc(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
|
let mut stats = unsafe { &mut self.props[4].u.st };
|
||||||
|
|
||||||
|
if stats.len == 0 || stats.stat[0].scale != FE_SCALE_COUNTER {
|
||||||
|
if let Ok(value) = fe.read_unc() {
|
||||||
|
stats.stat[0].scale = FE_SCALE_COUNTER;
|
||||||
|
stats.stat[0].value = i64::from(value);
|
||||||
|
} else {
|
||||||
|
stats.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||||
|
stats.stat[0].value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set decibel to `stat[0]` and relative to `stat[1]` and fallback to DVBv3 API
|
||||||
|
fn normalize_props(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
|
self.normalize_signal_strength(fe)?;
|
||||||
|
self.normalize_snr(fe)?;
|
||||||
|
self.normalize_ber(fe)?;
|
||||||
|
self.normalize_unc(fe)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads frontend status with fallback to DVBv3 API
|
||||||
pub fn read(&mut self, fe: &FeDevice) -> Result<()> {
|
pub fn read(&mut self, fe: &FeDevice) -> Result<()> {
|
||||||
self.status = FE_NONE;
|
self.status = fe.read_status()?;
|
||||||
|
|
||||||
// FE_READ_STATUS
|
|
||||||
ioctl_read!(#[inline] ioctl_call, b'o', 69, u32);
|
|
||||||
unsafe {
|
|
||||||
ioctl_call(fe.as_raw_fd(), &mut self.status as *mut _)
|
|
||||||
}.context("FE: read status")?;
|
|
||||||
|
|
||||||
if self.status == FE_NONE {
|
if self.status == FE_NONE {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fe.get_properties(&mut self.props)?;
|
fe.get_properties(&mut self.props)?;
|
||||||
|
self.normalize_props(fe)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user