Krolyxon
Commit 3dfc07c

Branches

Refs →

budctlcratesbudctl-coresrctransportrfcomm.rs

47 lines · 1.5 KB · Rust

1//! The RFCOMM control link: a byte stream to one channel on the buds.
2
3use std::os::fd::OwnedFd;
4use std::time::{Duration, Instant};
5
6use super::{Transport, classify, socket};
7use crate::bt::BdAddr;
8use crate::error::{Error, Result};
9
10/// Upper bound for the connect and for each send. The audio link is already up, so a healthy
11/// connect takes well under a second.
12const TIMEOUT: Duration = Duration::from_secs(8);
13
14pub struct Rfcomm {
15 fd: OwnedFd,
16}
17
18impl Rfcomm {
19 pub fn connect(address: BdAddr, channel: u8) -> Result<Self> {
20 let fd = socket::connect(address, socket::Target::Rfcomm { channel }, TIMEOUT)
21 .map_err(|e| classify(e, "connecting to the control channel", true))?;
22 Ok(Self { fd })
23 }
24}
25
26impl Transport for Rfcomm {
27 fn send(&mut self, bytes: &[u8]) -> Result<()> {
28 socket::write_all(&self.fd, bytes).map_err(|e| classify(e, "sending to the buds", false))
29 }
30
31 fn recv(&mut self, deadline: Instant) -> Result<Option<Vec<u8>>> {
32 let readable =
33 socket::wait_readable(&self.fd, deadline).map_err(|e| classify(e, "waiting for the buds", false))?;
34 if !readable {
35 return Ok(None);
36 }
37 let mut buffer = vec![0u8; 1024];
38 let n = socket::read(&self.fd, &mut buffer).map_err(|e| classify(e, "reading from the buds", false))?;
39 if n == 0 {
40 return Err(Error::NotConnected(
41 "the buds closed the control link (case lid closed?)".to_owned(),
42 ));
43 }
44 buffer.truncate(n);
45 Ok(Some(buffer))
46 }
47}