|
|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
//! Lirc programs.
|
|
|
|
|
use std::os::fd::{AsRawFd, RawFd};
|
|
|
|
|
use std::os::fd::{AsFd, AsRawFd, OwnedFd, RawFd};
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2},
|
|
|
|
|
@ -7,8 +7,6 @@ use crate::{
|
|
|
|
|
sys::{bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use libc::{close, dup};
|
|
|
|
|
|
|
|
|
|
/// A program used to decode IR into key events for a lirc device.
|
|
|
|
|
///
|
|
|
|
|
/// [`LircMode2`] programs can be used to inspect infrared pulses, spaces,
|
|
|
|
|
@ -60,9 +58,9 @@ impl LircMode2 {
|
|
|
|
|
/// Attaches the program to the given lirc device.
|
|
|
|
|
///
|
|
|
|
|
/// The returned value can be used to detach, see [LircMode2::detach].
|
|
|
|
|
pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<LircLinkId, ProgramError> {
|
|
|
|
|
pub fn attach<T: AsFd>(&mut self, lircdev: T) -> Result<LircLinkId, ProgramError> {
|
|
|
|
|
let prog_fd = self.data.fd_or_err()?;
|
|
|
|
|
let lircdev_fd = lircdev.as_raw_fd();
|
|
|
|
|
let lircdev_fd = lircdev.as_fd();
|
|
|
|
|
|
|
|
|
|
bpf_prog_attach(prog_fd, lircdev_fd, BPF_LIRC_MODE2).map_err(|(_, io_error)| {
|
|
|
|
|
ProgramError::SyscallError {
|
|
|
|
|
@ -72,9 +70,10 @@ impl LircMode2 {
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
// TODO (AM)
|
|
|
|
|
self.data
|
|
|
|
|
.links
|
|
|
|
|
.insert(LircLink::new(prog_fd.as_raw_fd(), lircdev_fd))
|
|
|
|
|
self.data.links.insert(LircLink::new(
|
|
|
|
|
prog_fd.as_raw_fd(),
|
|
|
|
|
lircdev_fd.try_clone_to_owned()?,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Detaches the program.
|
|
|
|
|
@ -93,8 +92,9 @@ impl LircMode2 {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Queries the lirc device for attached programs.
|
|
|
|
|
pub fn query<T: AsRawFd>(target_fd: T) -> Result<Vec<LircLink>, ProgramError> {
|
|
|
|
|
let prog_ids = query(target_fd.as_raw_fd(), BPF_LIRC_MODE2, 0, &mut None)?;
|
|
|
|
|
pub fn query<T: AsFd>(target_fd: T) -> Result<Vec<LircLink>, ProgramError> {
|
|
|
|
|
let target_fd = target_fd.as_fd();
|
|
|
|
|
let prog_ids = query(target_fd, BPF_LIRC_MODE2, 0, &mut None)?;
|
|
|
|
|
|
|
|
|
|
let mut prog_fds = Vec::with_capacity(prog_ids.len());
|
|
|
|
|
|
|
|
|
|
@ -107,10 +107,10 @@ impl LircMode2 {
|
|
|
|
|
prog_fds.push(fd as RawFd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(prog_fds
|
|
|
|
|
prog_fds
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|prog_fd| LircLink::new(prog_fd, target_fd.as_raw_fd()))
|
|
|
|
|
.collect())
|
|
|
|
|
.map(|prog_fd| Ok(LircLink::new(prog_fd, target_fd.try_clone_to_owned()?)))
|
|
|
|
|
.collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -122,15 +122,12 @@ pub struct LircLinkId(RawFd, RawFd);
|
|
|
|
|
/// An LircMode2 Link
|
|
|
|
|
pub struct LircLink {
|
|
|
|
|
prog_fd: RawFd,
|
|
|
|
|
target_fd: RawFd,
|
|
|
|
|
target_fd: OwnedFd,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LircLink {
|
|
|
|
|
pub(crate) fn new(prog_fd: RawFd, target_fd: RawFd) -> LircLink {
|
|
|
|
|
LircLink {
|
|
|
|
|
prog_fd,
|
|
|
|
|
target_fd: unsafe { dup(target_fd) },
|
|
|
|
|
}
|
|
|
|
|
pub(crate) fn new(prog_fd: RawFd, target_fd: OwnedFd) -> LircLink {
|
|
|
|
|
LircLink { prog_fd, target_fd }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Get ProgramInfo from this link
|
|
|
|
|
@ -149,12 +146,13 @@ impl Link for LircLink {
|
|
|
|
|
type Id = LircLinkId;
|
|
|
|
|
|
|
|
|
|
fn id(&self) -> Self::Id {
|
|
|
|
|
LircLinkId(self.prog_fd, self.target_fd)
|
|
|
|
|
// TODO (AM)
|
|
|
|
|
LircLinkId(self.prog_fd, self.target_fd.as_raw_fd())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn detach(self) -> Result<(), ProgramError> {
|
|
|
|
|
let _ = bpf_prog_detach(self.prog_fd, self.target_fd, BPF_LIRC_MODE2);
|
|
|
|
|
unsafe { close(self.target_fd) };
|
|
|
|
|
// TODO (AM)
|
|
|
|
|
let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), BPF_LIRC_MODE2);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|