use std::fmt;
use std::io;
use std::net::Shutdown;
use std::time::Duration;
use crate::sys_common::bt as bt_imp;
use crate::sys_common::{AsInner, FromInner, IntoInner};
#[derive(Clone)]
pub struct BtAddr(pub [u8; 6]);
impl BtAddr {
pub fn nap_sap(nap: u16, sap: u32) -> BtAddr {
let nap = nap.to_le_bytes();
let sap = sap.to_le_bytes();
Self([sap[0], sap[1], sap[2], sap[3], nap[0], nap[1]])
}
}
impl fmt::Debug for BtAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"BtAddr({:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x})",
self.0[5], self.0[4], self.0[3], self.0[2], self.0[1], self.0[0]
)
}
}
impl fmt::Display for BtAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
self.0[5], self.0[4], self.0[3], self.0[2], self.0[1], self.0[0]
)
}
}
#[derive(Clone, Copy)]
pub enum BtProtocol {
L2CAP,
RFCOMM,
}
pub use crate::sys::bt::discover_devices;
pub struct BtListener(bt_imp::BtListener);
pub struct BtStream(bt_imp::BtStream);
impl BtListener {
pub fn bind<'a, I>(addrs: I, protocol: BtProtocol) -> io::Result<Self>
where
I: Iterator<Item = &'a BtAddr>,
{
each_addr(addrs, |addr| bt_imp::BtListener::bind(addr, protocol)).map(BtListener)
}
pub fn accept(&self) -> io::Result<(BtStream, BtAddr)> {
#[cfg_attr(target_arch = "wasm32", allow(unused_variables))]
self.0.accept().map(|(a, b)| (BtStream(a), b))
}
pub fn local_addr(&self) -> io::Result<BtAddr> {
self.0.local_addr()
}
pub fn protocol(&self) -> BtProtocol {
self.0.protocol()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
self.0.take_error()
}
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
self.0.set_nonblocking(nonblocking)
}
pub fn try_clone(&self) -> io::Result<BtListener> {
self.0.duplicate().map(BtListener)
}
}
impl fmt::Debug for BtListener {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl AsInner<bt_imp::BtListener> for BtListener {
fn as_inner(&self) -> &bt_imp::BtListener {
&self.0
}
}
impl FromInner<bt_imp::BtListener> for BtListener {
fn from_inner(inner: bt_imp::BtListener) -> BtListener {
BtListener(inner)
}
}
impl IntoInner<bt_imp::BtListener> for BtListener {
fn into_inner(self) -> bt_imp::BtListener {
self.0
}
}
impl BtStream {
pub fn connect<'a, I: Iterator<Item = &'a BtAddr>>(
addrs: I,
protocol: BtProtocol,
) -> io::Result<Self> {
each_addr(addrs, |addr| bt_imp::BtStream::connect(addr, protocol)).map(BtStream)
}
pub fn connect_timeout(
addr: &BtAddr,
protocol: BtProtocol,
timeout: Duration,
) -> io::Result<Self> {
bt_imp::BtStream::connect_timeout(addr, protocol, timeout).map(BtStream)
}
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.peek(buf)
}
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, BtAddr)> {
self.0.peek_from(buf)
}
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.recv(buf)
}
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, BtAddr)> {
self.0.recv_from(buf)
}
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
self.0.send(buf)
}
pub fn send_to(&self, buf: &[u8], dst: &BtAddr) -> io::Result<usize> {
self.0.send_to(buf, dst)
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.0.shutdown(how)
}
pub fn local_addr(&self) -> io::Result<BtAddr> {
self.0.local_addr()
}
pub fn peer_addr(&self) -> io::Result<BtAddr> {
self.0.peer_addr()
}
pub fn protocol(&self) -> BtProtocol {
self.0.protocol()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
self.0.take_error()
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
self.0.read_timeout()
}
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_read_timeout(dur)
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
self.0.write_timeout()
}
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_write_timeout(dur)
}
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
self.0.set_nonblocking(nonblocking)
}
pub fn try_clone(&self) -> io::Result<Self> {
self.0.duplicate().map(BtStream)
}
}
impl fmt::Debug for BtStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl io::Read for BtStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.recv(buf)
}
}
impl io::Write for BtStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.send(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl AsInner<bt_imp::BtStream> for BtStream {
fn as_inner(&self) -> &bt_imp::BtStream {
&self.0
}
}
impl FromInner<bt_imp::BtStream> for BtStream {
fn from_inner(inner: bt_imp::BtStream) -> BtStream {
BtStream(inner)
}
}
impl IntoInner<bt_imp::BtStream> for BtStream {
fn into_inner(self) -> bt_imp::BtStream {
self.0
}
}
fn each_addr<'a, I, F, T>(addrs: I, mut f: F) -> io::Result<T>
where
F: FnMut(&'a BtAddr) -> io::Result<T>,
I: Iterator<Item = &'a BtAddr>,
{
let mut last_err = None;
for addr in addrs {
match f(addr) {
Ok(l) => return Ok(l),
Err(e) => last_err = Some(e),
}
}
Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
}
#[cfg(test)]
mod tests {}