diff options
| author | jamie <git@skilet.ro> | 2026-08-29 21:58:43 +0100 |
|---|---|---|
| committer | jamie <git@skilet.ro> | 2026-08-29 22:06:00 +0100 |
| commit | c1110ac81f87ba374696e419f3807f48a3a06d6d (patch) | |
| tree | 6d03e2747657c1b2e30baba309d4620ce3227eaf /src/hid.rs | |
| parent | 3061396dbb60b5b294c1c0c62c25da8de5c87ffb (diff) | |
feat(daemon): link-state hooks for headset connect/disconnect
Diffstat (limited to 'src/hid.rs')
| -rw-r--r-- | src/hid.rs | 46 |
1 files changed, 46 insertions, 0 deletions
@@ -10,6 +10,7 @@ use std::fs; use std::io; use std::os::fd::AsRawFd; use std::path::{Path, PathBuf}; +use std::time::{Duration, Instant}; /// beyerdynamic USB vendor ID. pub const BEYERDYNAMIC_VID: u16 = 0x2e50; @@ -198,6 +199,51 @@ impl Hidraw { self.file.read(buf) } + /// Wait up to `timeout` for one input report on the interrupt IN + /// endpoint. Returns `Ok(None)` if none arrived in time. + pub fn read_with_timeout(&mut self, timeout: Duration) -> io::Result<Option<Vec<u8>>> { + let deadline = Instant::now() + timeout; + loop { + let now = Instant::now(); + if now >= deadline { + return Ok(None); + } + let mut set = unsafe { std::mem::zeroed::<libc::fd_set>() }; + unsafe { libc::FD_ZERO(&mut set) }; + unsafe { libc::FD_SET(self.file.as_raw_fd(), &mut set) }; + let remaining = deadline.saturating_duration_since(now); + let mut tv = libc::timeval { + tv_sec: remaining.as_secs() as libc::time_t, + tv_usec: remaining.subsec_micros() as libc::suseconds_t, + }; + let n = unsafe { + libc::select( + self.file.as_raw_fd() + 1, + &mut set, + std::ptr::null_mut(), + std::ptr::null_mut(), + &mut tv, + ) + }; + if n < 0 { + let err = io::Error::last_os_error(); + if err.kind() == io::ErrorKind::Interrupted { + continue; + } + return Err(err); + } + if n == 0 { + return Ok(None); + } + let mut buf = [0u8; 256]; + match self.read(&mut buf) { + Ok(len) => return Ok(Some(buf[..len].to_vec())), + Err(e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => return Err(e), + } + } + } + /// Write to the interrupt OUT endpoint. pub fn write(&mut self, buf: &[u8]) -> io::Result<usize> { use std::io::Write; |
