mirror of
https://github.com/danog/libdvb.git
synced 2024-11-30 04:19:00 +01:00
Fixes
This commit is contained in:
parent
daafb43bec
commit
a33cd90986
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libdvb-rs"
|
name = "libdvb-rs"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
description = "Safer pure-Rust interface for DVB-API v5 devices in Linux"
|
description = "Safer pure-Rust interface for DVB-API v5 devices in Linux"
|
||||||
authors = ["Cesbo Developers Team <info@cesbo.com>", "Daniil Gentili <daniil@daniil.it>"]
|
authors = ["Cesbo Developers Team <info@cesbo.com>", "Daniil Gentili <daniil@daniil.it>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -16,5 +16,4 @@ nix = "0.19"
|
|||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
strum = { version = "0.23", features = ["derive"] }
|
strum = { version = "0.23", features = ["derive"] }
|
||||||
bitflags = "1.3.2"
|
bitflags = "1.3.2"
|
||||||
derive_more = "0.99.0"
|
|
||||||
itertools = "0.10.2"
|
itertools = "0.10.2"
|
@ -4,7 +4,7 @@
|
|||||||
//! All protocols in the Application Layer use a common Application
|
//! All protocols in the Application Layer use a common Application
|
||||||
//! Protocol Data Unit (APDU) structure to send application data between
|
//! Protocol Data Unit (APDU) structure to send application data between
|
||||||
//! module and host or between modules.
|
//! module and host or between modules.
|
||||||
|
#![allow(dead_code)]
|
||||||
use {super::CaDevice, anyhow::Result};
|
use {super::CaDevice, anyhow::Result};
|
||||||
|
|
||||||
pub const APDU_TAG_SIZE: usize = 3;
|
pub const APDU_TAG_SIZE: usize = 3;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
mod apdu;
|
mod apdu;
|
||||||
mod asn1;
|
mod asn1;
|
||||||
mod spdu;
|
mod spdu;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
//! The session layer uses a Session Protocol Data Unit (SPDU) structure
|
//! The session layer uses a Session Protocol Data Unit (SPDU) structure
|
||||||
//! to exchange data at session level either from the host to the module
|
//! to exchange data at session level either from the host to the module
|
||||||
//! or from the module to the host.
|
//! or from the module to the host.
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use {
|
use {
|
||||||
super::{apdu, tpdu, CaDevice},
|
super::{apdu, tpdu, CaDevice},
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
//! Transport Protocol Data Unit (R_TPDU).
|
//! Transport Protocol Data Unit (R_TPDU).
|
||||||
//! The module cannot initiate communication: it must wait for the host to
|
//! The module cannot initiate communication: it must wait for the host to
|
||||||
//! poll it or send it data first.
|
//! poll it or send it data first.
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use {
|
use {
|
||||||
super::{asn1, spdu, CaDevice},
|
super::{asn1, spdu, CaDevice},
|
||||||
|
115
src/fe/mod.rs
115
src/fe/mod.rs
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
mod status;
|
mod status;
|
||||||
pub mod sys;
|
pub mod sys;
|
||||||
|
|
||||||
@ -100,59 +101,9 @@ macro_rules! get_dtv_properties {
|
|||||||
macro_rules! set_dtv_properties {
|
macro_rules! set_dtv_properties {
|
||||||
( $device:expr, $( $property:ident($data:expr) ),+ ) => {
|
( $device:expr, $( $property:ident($data:expr) ),+ ) => {
|
||||||
$device.set_properties(&[
|
$device.set_properties(&[
|
||||||
$( set_dtv_properties!(inner $device, $property, $data), )*
|
$( $property(DtvPropertyRequest::new($data)), )*
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
( inner $device:expr, DTV_FREQUENCY, $data:expr ) => {
|
|
||||||
if !$device.frequency_range.contains($data) {
|
|
||||||
bail!("FE: frequency out of range");
|
|
||||||
} else {
|
|
||||||
DTV_FREQUENCY(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_SYMBOL_RATE, $data:expr ) => {
|
|
||||||
if !$device.symbolrate_range.contains($data) {
|
|
||||||
bail!("FE: symbolrate out of range");
|
|
||||||
} else {
|
|
||||||
DTV_SYMBOL_RATE(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_INVERSION, $data:expr ) => {
|
|
||||||
if $data == INVERSION_AUTO && !$device.caps.contains(fe_caps::FE_CAN_INVERSION_AUTO) {
|
|
||||||
bail!("FE: auto inversion is not available");
|
|
||||||
} else {
|
|
||||||
DTV_INVERSION(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_TRANSMISSION_MODE, $data:expr ) => {
|
|
||||||
if $data == TRANSMISSION_MODE_AUTO && !$device.caps.contains(fe_caps::FE_CAN_TRANSMISSION_MODE_AUTO) {
|
|
||||||
bail!("FE: no auto transmission mode");
|
|
||||||
} else {
|
|
||||||
DTV_TRANSMISSION_MODE(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_GUARD_INTERVAL, $data:expr ) => {
|
|
||||||
if $data == GUARD_INTERVAL_AUTO && !$device.caps.contains(fe_caps::FE_CAN_GUARD_INTERVAL_AUTO) {
|
|
||||||
bail!("FE: no auto guard interval");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_HIERARCHY, $data:expr ) => {
|
|
||||||
if $data == HIERARCHY_AUTO && !$device.caps.contains(fe_caps::FE_CAN_HIERARCHY_AUTO) {
|
|
||||||
bail!("FE: no auto hierarchy");
|
|
||||||
} else {
|
|
||||||
DTV_HIERARCHY(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, DTV_STREAM_ID, $data:expr ) => {
|
|
||||||
if !$device.caps.contains(fe_caps::FE_CAN_MULTISTREAM) {
|
|
||||||
bail!("FE: no multistream");
|
|
||||||
} else {
|
|
||||||
DTV_STREAM_ID(DtvPropertyRequest::new($data:expr))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
( inner $device:expr, $property:ident, $data:expr ) => {
|
|
||||||
$property(DtvPropertyRequest::new($data))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FeDevice {
|
impl FeDevice {
|
||||||
@ -266,8 +217,70 @@ impl FeDevice {
|
|||||||
Self::open(adapter, device, true)
|
Self::open(adapter, device, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_properties(&self, cmdseq: &[DtvProperty]) -> Result<()> {
|
||||||
|
for p in cmdseq {
|
||||||
|
match p {
|
||||||
|
DTV_FREQUENCY(d) => {
|
||||||
|
ensure!(
|
||||||
|
self.frequency_range.contains(&d.get()?),
|
||||||
|
"FE: frequency out of range"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
DTV_SYMBOL_RATE(d) => {
|
||||||
|
ensure!(
|
||||||
|
self.symbolrate_range.contains(&d.get()?),
|
||||||
|
"FE: symbolrate out of range"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
DTV_INVERSION(d) => {
|
||||||
|
if d.get()? == INVERSION_AUTO {
|
||||||
|
ensure!(
|
||||||
|
self.caps.contains(fe_caps::FE_CAN_INVERSION_AUTO),
|
||||||
|
"FE: auto inversion is not available"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DTV_TRANSMISSION_MODE(d) => {
|
||||||
|
if d.get()? == TRANSMISSION_MODE_AUTO {
|
||||||
|
ensure!(
|
||||||
|
self.caps.contains(fe_caps::FE_CAN_TRANSMISSION_MODE_AUTO),
|
||||||
|
"FE: no auto transmission mode"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DTV_GUARD_INTERVAL(d) => {
|
||||||
|
if d.get()? == GUARD_INTERVAL_AUTO {
|
||||||
|
ensure!(
|
||||||
|
self.caps.contains(fe_caps::FE_CAN_GUARD_INTERVAL_AUTO),
|
||||||
|
"FE: no auto guard interval"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DTV_HIERARCHY(d) => {
|
||||||
|
if d.get()? == HIERARCHY_AUTO {
|
||||||
|
ensure!(
|
||||||
|
self.caps.contains(fe_caps::FE_CAN_HIERARCHY_AUTO),
|
||||||
|
"FE: no auto hierarchy"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DTV_STREAM_ID(..) => {
|
||||||
|
ensure!(
|
||||||
|
self.caps.contains(fe_caps::FE_CAN_MULTISTREAM),
|
||||||
|
"FE: no multistream"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets properties on frontend device
|
/// Sets properties on frontend device
|
||||||
pub fn set_properties(&self, cmdseq: &[DtvProperty]) -> Result<()> {
|
pub fn set_properties(&self, cmdseq: &[DtvProperty]) -> Result<()> {
|
||||||
|
self.check_properties(cmdseq)?;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DtvProperties {
|
pub struct DtvProperties {
|
||||||
num: u32,
|
num: u32,
|
||||||
|
251
src/fe/sys.rs
251
src/fe/sys.rs
@ -1,5 +1,7 @@
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use std::{fmt, iter::FromIterator, mem};
|
use std::fmt::Debug;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::{fmt, mem};
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
fe_code_rate::*, fe_delivery_system::*, fe_guard_interval::*, fe_hierarchy::*,
|
fe_code_rate::*, fe_delivery_system::*, fe_guard_interval::*, fe_hierarchy::*,
|
||||||
@ -182,7 +184,7 @@ impl Default for DiseqcSlaveReply {
|
|||||||
/// DC Voltage used to feed the LNBf
|
/// DC Voltage used to feed the LNBf
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromRepr)]
|
#[derive(EnumString, Debug, Copy, Clone, PartialEq, Eq, FromRepr)]
|
||||||
pub enum fe_sec_voltage {
|
pub enum fe_sec_voltage {
|
||||||
/// Output 13V to the LNB. Vertical linear. Right circular.
|
/// Output 13V to the LNB. Vertical linear. Right circular.
|
||||||
SEC_VOLTAGE_13 = 0,
|
SEC_VOLTAGE_13 = 0,
|
||||||
@ -194,7 +196,7 @@ pub enum fe_sec_voltage {
|
|||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromRepr)]
|
#[derive(EnumString, Debug, Copy, Clone, PartialEq, Eq, FromRepr)]
|
||||||
pub enum fe_sec_tone_mode {
|
pub enum fe_sec_tone_mode {
|
||||||
/// Sends a 22kHz tone burst to the antenna
|
/// Sends a 22kHz tone burst to the antenna
|
||||||
SEC_TONE_ON = 0,
|
SEC_TONE_ON = 0,
|
||||||
@ -240,114 +242,178 @@ bitflags! {
|
|||||||
/// Spectral band inversion
|
/// Spectral band inversion
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Clone, Copy)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Clone, Copy)]
|
||||||
pub enum fe_spectral_inversion {
|
pub enum fe_spectral_inversion {
|
||||||
|
#[strum(serialize = "OFF")]
|
||||||
INVERSION_OFF = 0,
|
INVERSION_OFF = 0,
|
||||||
|
#[strum(serialize = "ON")]
|
||||||
INVERSION_ON = 1,
|
INVERSION_ON = 1,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
INVERSION_AUTO = 2,
|
INVERSION_AUTO = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Clone, Copy)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Clone, Copy)]
|
||||||
|
#[strum(ascii_case_insensitive)]
|
||||||
pub enum fe_code_rate {
|
pub enum fe_code_rate {
|
||||||
|
#[strum(serialize = "NONE")]
|
||||||
FEC_NONE = 0,
|
FEC_NONE = 0,
|
||||||
|
#[strum(serialize = "1/2")]
|
||||||
FEC_1_2 = 1,
|
FEC_1_2 = 1,
|
||||||
|
#[strum(serialize = "2/3")]
|
||||||
FEC_2_3 = 2,
|
FEC_2_3 = 2,
|
||||||
|
#[strum(serialize = "3/4")]
|
||||||
FEC_3_4 = 3,
|
FEC_3_4 = 3,
|
||||||
|
#[strum(serialize = "4/5")]
|
||||||
FEC_4_5 = 4,
|
FEC_4_5 = 4,
|
||||||
|
#[strum(serialize = "5/6")]
|
||||||
FEC_5_6 = 5,
|
FEC_5_6 = 5,
|
||||||
|
#[strum(serialize = "6/7")]
|
||||||
FEC_6_7 = 6,
|
FEC_6_7 = 6,
|
||||||
|
#[strum(serialize = "7/8")]
|
||||||
FEC_7_8 = 7,
|
FEC_7_8 = 7,
|
||||||
|
#[strum(serialize = "8/9")]
|
||||||
FEC_8_9 = 8,
|
FEC_8_9 = 8,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
FEC_AUTO = 9,
|
FEC_AUTO = 9,
|
||||||
|
#[strum(serialize = "3/5")]
|
||||||
FEC_3_5 = 10,
|
FEC_3_5 = 10,
|
||||||
|
#[strum(serialize = "9/10")]
|
||||||
FEC_9_10 = 11,
|
FEC_9_10 = 11,
|
||||||
|
#[strum(serialize = "2/5")]
|
||||||
FEC_2_5 = 12,
|
FEC_2_5 = 12,
|
||||||
|
#[strum(serialize = "1/4")]
|
||||||
FEC_1_4 = 13,
|
FEC_1_4 = 13,
|
||||||
|
#[strum(serialize = "1/3")]
|
||||||
FEC_1_3 = 14,
|
FEC_1_3 = 14,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type of modulation/constellation
|
/// Type of modulation/constellation
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_modulation {
|
pub enum fe_modulation {
|
||||||
QPSK = 0,
|
QPSK = 0,
|
||||||
|
#[strum(serialize = "QAM/16")]
|
||||||
QAM_16 = 1,
|
QAM_16 = 1,
|
||||||
|
#[strum(serialize = "QAM/32")]
|
||||||
QAM_32 = 2,
|
QAM_32 = 2,
|
||||||
|
#[strum(serialize = "QAM/64")]
|
||||||
QAM_64 = 3,
|
QAM_64 = 3,
|
||||||
|
#[strum(serialize = "QAM/128")]
|
||||||
QAM_128 = 4,
|
QAM_128 = 4,
|
||||||
|
#[strum(serialize = "QAM/256")]
|
||||||
QAM_256 = 5,
|
QAM_256 = 5,
|
||||||
|
#[strum(serialize = "QAM/AUTO")]
|
||||||
QAM_AUTO = 6,
|
QAM_AUTO = 6,
|
||||||
|
#[strum(serialize = "VSB/8")]
|
||||||
VSB_8 = 7,
|
VSB_8 = 7,
|
||||||
|
#[strum(serialize = "VSB/16")]
|
||||||
VSB_16 = 8,
|
VSB_16 = 8,
|
||||||
|
#[strum(serialize = "PSK/8")]
|
||||||
PSK_8 = 9,
|
PSK_8 = 9,
|
||||||
|
#[strum(serialize = "APSK/16")]
|
||||||
APSK_16 = 10,
|
APSK_16 = 10,
|
||||||
|
#[strum(serialize = "APSK/32")]
|
||||||
APSK_32 = 11,
|
APSK_32 = 11,
|
||||||
|
#[strum(serialize = "DQPSK")]
|
||||||
DQPSK = 12,
|
DQPSK = 12,
|
||||||
|
#[strum(serialize = "QAM/4/NR")]
|
||||||
QAM_4_NR = 13,
|
QAM_4_NR = 13,
|
||||||
|
#[strum(serialize = "APSK/64")]
|
||||||
APSK_64 = 14,
|
APSK_64 = 14,
|
||||||
|
#[strum(serialize = "APSK/128")]
|
||||||
APSK_128 = 15,
|
APSK_128 = 15,
|
||||||
|
#[strum(serialize = "APSK/256")]
|
||||||
APSK_256 = 16,
|
APSK_256 = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_transmit_mode {
|
pub enum fe_transmit_mode {
|
||||||
|
#[strum(serialize = "2K")]
|
||||||
TRANSMISSION_MODE_2K = 0,
|
TRANSMISSION_MODE_2K = 0,
|
||||||
|
#[strum(serialize = "8K")]
|
||||||
TRANSMISSION_MODE_8K = 1,
|
TRANSMISSION_MODE_8K = 1,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
TRANSMISSION_MODE_AUTO = 2,
|
TRANSMISSION_MODE_AUTO = 2,
|
||||||
|
#[strum(serialize = "4K")]
|
||||||
TRANSMISSION_MODE_4K = 3,
|
TRANSMISSION_MODE_4K = 3,
|
||||||
|
#[strum(serialize = "1K")]
|
||||||
TRANSMISSION_MODE_1K = 4,
|
TRANSMISSION_MODE_1K = 4,
|
||||||
|
#[strum(serialize = "16K")]
|
||||||
TRANSMISSION_MODE_16K = 5,
|
TRANSMISSION_MODE_16K = 5,
|
||||||
|
#[strum(serialize = "32K")]
|
||||||
TRANSMISSION_MODE_32K = 6,
|
TRANSMISSION_MODE_32K = 6,
|
||||||
|
#[strum(serialize = "C1")]
|
||||||
TRANSMISSION_MODE_C1 = 7,
|
TRANSMISSION_MODE_C1 = 7,
|
||||||
|
#[strum(serialize = "C3780")]
|
||||||
TRANSMISSION_MODE_C3780 = 8,
|
TRANSMISSION_MODE_C3780 = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_guard_interval {
|
pub enum fe_guard_interval {
|
||||||
|
#[strum(serialize = "1/32")]
|
||||||
GUARD_INTERVAL_1_32 = 0,
|
GUARD_INTERVAL_1_32 = 0,
|
||||||
|
#[strum(serialize = "1/16")]
|
||||||
GUARD_INTERVAL_1_16 = 1,
|
GUARD_INTERVAL_1_16 = 1,
|
||||||
|
#[strum(serialize = "1/8")]
|
||||||
GUARD_INTERVAL_1_8 = 2,
|
GUARD_INTERVAL_1_8 = 2,
|
||||||
|
#[strum(serialize = "1/4")]
|
||||||
GUARD_INTERVAL_1_4 = 3,
|
GUARD_INTERVAL_1_4 = 3,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
GUARD_INTERVAL_AUTO = 4,
|
GUARD_INTERVAL_AUTO = 4,
|
||||||
|
#[strum(serialize = "1/128")]
|
||||||
GUARD_INTERVAL_1_128 = 5,
|
GUARD_INTERVAL_1_128 = 5,
|
||||||
|
#[strum(serialize = "19/128")]
|
||||||
GUARD_INTERVAL_19_128 = 6,
|
GUARD_INTERVAL_19_128 = 6,
|
||||||
|
#[strum(serialize = "19/256")]
|
||||||
GUARD_INTERVAL_19_256 = 7,
|
GUARD_INTERVAL_19_256 = 7,
|
||||||
|
#[strum(serialize = "PN420")]
|
||||||
GUARD_INTERVAL_PN420 = 8,
|
GUARD_INTERVAL_PN420 = 8,
|
||||||
|
#[strum(serialize = "PN595")]
|
||||||
GUARD_INTERVAL_PN595 = 9,
|
GUARD_INTERVAL_PN595 = 9,
|
||||||
|
#[strum(serialize = "PN945")]
|
||||||
GUARD_INTERVAL_PN945 = 10,
|
GUARD_INTERVAL_PN945 = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_hierarchy {
|
pub enum fe_hierarchy {
|
||||||
|
#[strum(serialize = "NONE")]
|
||||||
HIERARCHY_NONE = 0,
|
HIERARCHY_NONE = 0,
|
||||||
|
#[strum(serialize = "1")]
|
||||||
HIERARCHY_1 = 1,
|
HIERARCHY_1 = 1,
|
||||||
|
#[strum(serialize = "2")]
|
||||||
HIERARCHY_2 = 2,
|
HIERARCHY_2 = 2,
|
||||||
|
#[strum(serialize = "4")]
|
||||||
HIERARCHY_4 = 3,
|
HIERARCHY_4 = 3,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
HIERARCHY_AUTO = 4,
|
HIERARCHY_AUTO = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_interleaving {
|
pub enum fe_interleaving {
|
||||||
|
#[strum(serialize = "NONE")]
|
||||||
INTERLEAVING_NONE = 0,
|
INTERLEAVING_NONE = 0,
|
||||||
|
#[strum(serialize = "AUTO")]
|
||||||
INTERLEAVING_AUTO = 1,
|
INTERLEAVING_AUTO = 1,
|
||||||
|
#[strum(serialize = "240")]
|
||||||
INTERLEAVING_240 = 2,
|
INTERLEAVING_240 = 2,
|
||||||
|
#[strum(serialize = "720")]
|
||||||
INTERLEAVING_720 = 3,
|
INTERLEAVING_720 = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_pilot {
|
pub enum fe_pilot {
|
||||||
PILOT_ON = 0,
|
PILOT_ON = 0,
|
||||||
PILOT_OFF = 1,
|
PILOT_OFF = 1,
|
||||||
@ -356,7 +422,7 @@ pub enum fe_pilot {
|
|||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_rolloff {
|
pub enum fe_rolloff {
|
||||||
ROLLOFF_35 = 0,
|
ROLLOFF_35 = 0,
|
||||||
ROLLOFF_20 = 1,
|
ROLLOFF_20 = 1,
|
||||||
@ -370,28 +436,29 @@ pub enum fe_rolloff {
|
|||||||
#[derive(EnumString, Display, FromRepr, Debug, Copy, Clone)]
|
#[derive(EnumString, Display, FromRepr, Debug, Copy, Clone)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
#[strum(ascii_case_insensitive)]
|
||||||
pub enum fe_delivery_system {
|
pub enum fe_delivery_system {
|
||||||
#[strum(to_string = "none")]
|
#[strum(to_string = "none")]
|
||||||
SYS_UNDEFINED = 0,
|
SYS_UNDEFINED = 0,
|
||||||
#[strum(to_string = "dvb-c")]
|
#[strum(to_string = "dbvc/annex_a")]
|
||||||
SYS_DVBC_ANNEX_A = 1,
|
SYS_DVBC_ANNEX_A = 1,
|
||||||
#[strum(to_string = "dvb-c/b")]
|
#[strum(to_string = "dvbc/annex_b")]
|
||||||
SYS_DVBC_ANNEX_B = 2,
|
SYS_DVBC_ANNEX_B = 2,
|
||||||
#[strum(to_string = "dvb-t")]
|
#[strum(to_string = "dvbt")]
|
||||||
SYS_DVBT = 3,
|
SYS_DVBT = 3,
|
||||||
#[strum(to_string = "dss")]
|
#[strum(to_string = "dss")]
|
||||||
SYS_DSS = 4,
|
SYS_DSS = 4,
|
||||||
#[strum(to_string = "dvb-s")]
|
#[strum(to_string = "dvbs")]
|
||||||
SYS_DVBS = 5,
|
SYS_DVBS = 5,
|
||||||
#[strum(to_string = "dvb-s2")]
|
#[strum(to_string = "dvbs2")]
|
||||||
SYS_DVBS2 = 6,
|
SYS_DVBS2 = 6,
|
||||||
#[strum(to_string = "dvb-h")]
|
#[strum(to_string = "dvbh")]
|
||||||
SYS_DVBH = 7,
|
SYS_DVBH = 7,
|
||||||
#[strum(to_string = "isdb-t")]
|
#[strum(to_string = "isdbt")]
|
||||||
SYS_ISDBT = 8,
|
SYS_ISDBT = 8,
|
||||||
#[strum(to_string = "isdb-s")]
|
#[strum(to_string = "isdbs")]
|
||||||
SYS_ISDBS = 9,
|
SYS_ISDBS = 9,
|
||||||
#[strum(to_string = "isdb-c")]
|
#[strum(to_string = "isdbc")]
|
||||||
SYS_ISDBC = 10,
|
SYS_ISDBC = 10,
|
||||||
#[strum(to_string = "atsc")]
|
#[strum(to_string = "atsc")]
|
||||||
SYS_ATSC = 11,
|
SYS_ATSC = 11,
|
||||||
@ -403,19 +470,19 @@ pub enum fe_delivery_system {
|
|||||||
SYS_CMMB = 14,
|
SYS_CMMB = 14,
|
||||||
#[strum(to_string = "dab")]
|
#[strum(to_string = "dab")]
|
||||||
SYS_DAB = 15,
|
SYS_DAB = 15,
|
||||||
#[strum(to_string = "dvb-t2")]
|
#[strum(to_string = "dvbt2", serialize = "dvbt22")]
|
||||||
SYS_DVBT2 = 16,
|
SYS_DVBT2 = 16,
|
||||||
#[strum(to_string = "dvb-s/turbo")]
|
#[strum(to_string = "dvbs/turbo")]
|
||||||
SYS_TURBO = 17,
|
SYS_TURBO = 17,
|
||||||
#[strum(to_string = "dvb-c/c")]
|
#[strum(to_string = "dvbc/annex_c")]
|
||||||
SYS_DVBC_ANNEX_C = 18,
|
SYS_DVBC_ANNEX_C = 18,
|
||||||
#[strum(to_string = "dvb-c2")]
|
#[strum(to_string = "dvbc2")]
|
||||||
SYS_DVBC2 = 19,
|
SYS_DVBC2 = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
#[derive(EnumString, Debug, PartialEq, Eq, FromRepr, Copy, Clone)]
|
||||||
pub enum fe_lna {
|
pub enum fe_lna {
|
||||||
LNA_OFF = 0,
|
LNA_OFF = 0,
|
||||||
LNA_ON = 1,
|
LNA_ON = 1,
|
||||||
@ -615,15 +682,27 @@ impl WrappedResult<()> for DtvPropertyRequestVoid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for DtvPropertyRequestVoid {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str("()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type DtvPropertyRequestInt<T> = DtvPropertyRequest<T, { DATA_SIZE - 4 }>;
|
pub type DtvPropertyRequestInt<T> = DtvPropertyRequest<T, { DATA_SIZE - 4 }>;
|
||||||
|
|
||||||
impl<T: Copy> WrappedResult<T> for DtvPropertyRequestInt<T> {
|
impl<T: Copy + Debug> WrappedResult<T> for DtvPropertyRequestInt<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self) -> anyhow::Result<T> {
|
fn get(&self) -> anyhow::Result<T> {
|
||||||
Ok(self.data)
|
Ok(self.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Copy + Debug> Debug for DtvPropertyRequestInt<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.get().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type DtvPropertyRequestFrontendStats = DtvPropertyRequest<DtvFrontendStats, { DATA_SIZE - 37 }>;
|
pub type DtvPropertyRequestFrontendStats = DtvPropertyRequest<DtvFrontendStats, { DATA_SIZE - 37 }>;
|
||||||
|
|
||||||
impl WrappedResult<DtvFrontendStats> for DtvPropertyRequestFrontendStats {
|
impl WrappedResult<DtvFrontendStats> for DtvPropertyRequestFrontendStats {
|
||||||
@ -633,12 +712,18 @@ impl WrappedResult<DtvFrontendStats> for DtvPropertyRequestFrontendStats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for DtvPropertyRequestFrontendStats {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.data.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type DtvPropertyRequestDeliverySystems =
|
pub type DtvPropertyRequestDeliverySystems =
|
||||||
DtvPropertyRequest<DtvPropertyBuffer, { DATA_SIZE - 4 - 32 }>;
|
DtvPropertyRequest<DtvPropertyBuffer, { DATA_SIZE - 4 - 32 }>;
|
||||||
|
|
||||||
impl<T: FromIterator<fe_delivery_system>> WrappedResult<T> for DtvPropertyRequestDeliverySystems {
|
impl WrappedResult<Vec<fe_delivery_system>> for DtvPropertyRequestDeliverySystems {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self) -> Result<T, anyhow::Error> {
|
fn get(&self) -> Result<Vec<fe_delivery_system>, anyhow::Error> {
|
||||||
self.data
|
self.data
|
||||||
.slice()
|
.slice()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -647,9 +732,21 @@ impl<T: FromIterator<fe_delivery_system>> WrappedResult<T> for DtvPropertyReques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for DtvPropertyRequestDeliverySystems {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_list().entries(self.get().unwrap().iter()).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
pub struct DtvPropertyNotImplementedLinux {
|
pub struct DtvPropertyNotImplementedLinux {
|
||||||
__reserved: [u32; 6],
|
__reserved: [u8; DATA_SIZE],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DtvPropertyNotImplementedLinux {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str("Not implemented")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
@ -663,6 +760,7 @@ type DtvPropertyDeprecated = DtvPropertyNotImplementedLinux;
|
|||||||
#[repr(u32, C)]
|
#[repr(u32, C)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum DtvProperty {
|
pub enum DtvProperty {
|
||||||
DTV_UNDEFINED(DtvPropertyNotImplementedLinux),
|
DTV_UNDEFINED(DtvPropertyNotImplementedLinux),
|
||||||
DTV_TUNE(DtvPropertyRequestVoid),
|
DTV_TUNE(DtvPropertyRequestVoid),
|
||||||
@ -712,8 +810,8 @@ pub enum DtvProperty {
|
|||||||
DTV_API_VERSION(DtvPropertyRequestInt<u32>),
|
DTV_API_VERSION(DtvPropertyRequestInt<u32>),
|
||||||
|
|
||||||
/* DVB-T/T2 */
|
/* DVB-T/T2 */
|
||||||
DTV_CODE_RATE_HP(DtvPropertyRequestInt<fe_transmit_mode>),
|
DTV_CODE_RATE_HP(DtvPropertyRequestInt<fe_code_rate>),
|
||||||
DTV_CODE_RATE_LP(DtvPropertyRequestInt<fe_transmit_mode>),
|
DTV_CODE_RATE_LP(DtvPropertyRequestInt<fe_code_rate>),
|
||||||
DTV_GUARD_INTERVAL(DtvPropertyRequestInt<fe_guard_interval>),
|
DTV_GUARD_INTERVAL(DtvPropertyRequestInt<fe_guard_interval>),
|
||||||
DTV_TRANSMISSION_MODE(DtvPropertyRequestInt<fe_transmit_mode>),
|
DTV_TRANSMISSION_MODE(DtvPropertyRequestInt<fe_transmit_mode>),
|
||||||
DTV_HIERARCHY(DtvPropertyRequestInt<fe_hierarchy>),
|
DTV_HIERARCHY(DtvPropertyRequestInt<fe_hierarchy>),
|
||||||
@ -760,6 +858,95 @@ pub enum DtvProperty {
|
|||||||
DTV_SCRAMBLING_SEQUENCE_INDEX(DtvPropertyRequestInt<u32>),
|
DTV_SCRAMBLING_SEQUENCE_INDEX(DtvPropertyRequestInt<u32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dtv_property {
|
||||||
|
( $property:ident($data:expr) ) => {
|
||||||
|
$property(DtvPropertyRequest::new($data))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dtv_property_parse {
|
||||||
|
( $property:ident($data:expr)) => {
|
||||||
|
$property(DtvPropertyRequest::new($data.parse().context(format!("Invalid {}: {}", stringify!($property), $data))?))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for DtvProperty {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let (k, v) = s.split_once('=').context("Invalid line")?;
|
||||||
|
let v = v.trim();
|
||||||
|
Ok(match k.trim() {
|
||||||
|
"FREQUENCY" => dtv_property_parse!(DTV_FREQUENCY(v)),
|
||||||
|
"MODULATION" => dtv_property_parse!(DTV_MODULATION(v)),
|
||||||
|
"BANDWIDTH_HZ" => dtv_property_parse!(DTV_BANDWIDTH_HZ(v)),
|
||||||
|
"INVERSION" => dtv_property_parse!(DTV_INVERSION(v)),
|
||||||
|
"SYMBOL_RATE" => dtv_property_parse!(DTV_SYMBOL_RATE(v)),
|
||||||
|
"INNER_FEC" => dtv_property_parse!(DTV_INNER_FEC(v)),
|
||||||
|
"VOLTAGE" => dtv_property_parse!(DTV_VOLTAGE(v)),
|
||||||
|
"TONE" => dtv_property_parse!(DTV_TONE(v)),
|
||||||
|
"PILOT" => dtv_property_parse!(DTV_PILOT(v)),
|
||||||
|
"ROLLOFF" => dtv_property_parse!(DTV_ROLLOFF(v)),
|
||||||
|
|
||||||
|
/* Basic enumeration set for querying unlimited capabilities */
|
||||||
|
"DELIVERY_SYSTEM" => dtv_property_parse!(DTV_DELIVERY_SYSTEM(v)),
|
||||||
|
|
||||||
|
/* ISDB-T and ISDB-Tsb */
|
||||||
|
"ISDBT_PARTIAL_RECEPTION" => dtv_property_parse!(DTV_ISDBT_PARTIAL_RECEPTION(v)),
|
||||||
|
"ISDBT_SOUND_BROADCASTING" => dtv_property_parse!(DTV_ISDBT_SOUND_BROADCASTING(v)),
|
||||||
|
|
||||||
|
"ISDBT_SB_SUBCHANNEL_ID" => dtv_property_parse!(DTV_ISDBT_SB_SUBCHANNEL_ID(v)),
|
||||||
|
"ISDBT_SB_SEGMENT_IDX" => dtv_property_parse!(DTV_ISDBT_SB_SEGMENT_IDX(v)),
|
||||||
|
"ISDBT_SB_SEGMENT_COUNT" => dtv_property_parse!(DTV_ISDBT_SB_SEGMENT_COUNT(v)),
|
||||||
|
|
||||||
|
"ISDBT_LAYERA_FEC" => dtv_property_parse!(DTV_ISDBT_LAYERA_FEC(v)),
|
||||||
|
"ISDBT_LAYERA_MODULATION" => dtv_property_parse!(DTV_ISDBT_LAYERA_MODULATION(v)),
|
||||||
|
"ISDBT_LAYERA_SEGMENT_COUNT" => dtv_property_parse!(DTV_ISDBT_LAYERA_SEGMENT_COUNT(v)),
|
||||||
|
"ISDBT_LAYERA_TIME_INTERLEAVING" => {
|
||||||
|
dtv_property_parse!(DTV_ISDBT_LAYERA_TIME_INTERLEAVING(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
"ISDBT_LAYERB_FEC" => dtv_property_parse!(DTV_ISDBT_LAYERB_FEC(v)),
|
||||||
|
"ISDBT_LAYERB_MODULATION" => dtv_property_parse!(DTV_ISDBT_LAYERB_MODULATION(v)),
|
||||||
|
"ISDBT_LAYERB_SEGMENT_COUNT" => dtv_property_parse!(DTV_ISDBT_LAYERB_SEGMENT_COUNT(v)),
|
||||||
|
"ISDBT_LAYERB_TIME_INTERLEAVING" => {
|
||||||
|
dtv_property_parse!(DTV_ISDBT_LAYERB_TIME_INTERLEAVING(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
"ISDBT_LAYERC_FEC" => dtv_property_parse!(DTV_ISDBT_LAYERC_FEC(v)),
|
||||||
|
"ISDBT_LAYERC_MODULATION" => dtv_property_parse!(DTV_ISDBT_LAYERC_MODULATION(v)),
|
||||||
|
"ISDBT_LAYERC_SEGMENT_COUNT" => dtv_property_parse!(DTV_ISDBT_LAYERC_SEGMENT_COUNT(v)),
|
||||||
|
"ISDBT_LAYERC_TIME_INTERLEAVING" => {
|
||||||
|
dtv_property_parse!(DTV_ISDBT_LAYERC_TIME_INTERLEAVING(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DVB-T/T2 */
|
||||||
|
"CODE_RATE_HP" => dtv_property_parse!(DTV_CODE_RATE_HP(v)),
|
||||||
|
"CODE_RATE_LP" => dtv_property_parse!(DTV_CODE_RATE_LP(v)),
|
||||||
|
"GUARD_INTERVAL" => dtv_property_parse!(DTV_GUARD_INTERVAL(v)),
|
||||||
|
"TRANSMISSION_MODE" => dtv_property_parse!(DTV_TRANSMISSION_MODE(v)),
|
||||||
|
"HIERARCHY" => dtv_property_parse!(DTV_HIERARCHY(v)),
|
||||||
|
|
||||||
|
"ISDBT_LAYER_ENABLED" => dtv_property_parse!(DTV_ISDBT_LAYER_ENABLED(v)),
|
||||||
|
|
||||||
|
"STREAM_ID" => dtv_property_parse!(DTV_STREAM_ID(v)),
|
||||||
|
|
||||||
|
/* ATSC-MH */
|
||||||
|
"ATSCMH_FIC_VER" => dtv_property_parse!(DTV_ATSCMH_FIC_VER(v)),
|
||||||
|
"ATSCMH_PARADE_ID" => dtv_property_parse!(DTV_ATSCMH_PARADE_ID(v)),
|
||||||
|
"ATSCMH_NOG" => dtv_property_parse!(DTV_ATSCMH_NOG(v)),
|
||||||
|
"ATSCMH_TNOG" => dtv_property_parse!(DTV_ATSCMH_TNOG(v)),
|
||||||
|
"ATSCMH_SGN" => dtv_property_parse!(DTV_ATSCMH_SGN(v)),
|
||||||
|
"ATSCMH_PRC" => dtv_property_parse!(DTV_ATSCMH_PRC(v)),
|
||||||
|
|
||||||
|
"INTERLEAVING" => dtv_property_parse!(DTV_INTERLEAVING(v)),
|
||||||
|
"LNA" => dtv_property_parse!(DTV_LNA(v)),
|
||||||
|
&_ => bail!("Invalid key {}", k),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl
|
/// num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl
|
||||||
pub const DTV_IOCTL_MAX_MSGS: usize = 64;
|
pub const DTV_IOCTL_MAX_MSGS: usize = 64;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user