1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::addr::ToHciSocketAddr;
use crate::internal::bt as bt_impl;

use std::io;

/// A HCI raw socket.
///
/// Allows exchanging HCI messages with the given device on selected
/// channel.
///
/// After creating a `HciSocket` by [`bind`]ing it to a HCI socket address
/// the messages can be [`send`] to and [`received`] from a Bluetooth
/// subsystem.
///
/// [`bind`]: #method.bind
/// [`send`]: #method.send
/// [`received`]: #method.recv
///
/// # Examples
///
/// ```no_run
/// use hciraw::{HciChannel, HciSocket, HciSocketAddr};
///
/// let addr = hciraw::HciSocketAddr::new(None, HciChannel::Control);
/// let socket = hciraw::HciSocket::bind(addr).expect("Error binding socket");
///
/// let sdata: [u8; 6] = [0x01, 0x00, 0xff, 0xff, 0x00, 0x00];
/// let snum = socket.send(&sdata).expect("Error sending data");
///
/// let mut rbuf = vec![0;128];
/// let rnum = socket.recv(rbuf.as_mut_slice()).expect("Error reading data");
/// ```
pub struct HciSocket(bt_impl::HciSocket);

impl HciSocket {
    /// Creates HCI raw socket from the given address. The socket, when created,
    /// is in the bound state.
    ///
    /// The address type can be any implementator of ToHciSocketAddr trait.
    ///
    /// # Examples
    ///
    /// Creates HCI raw socket bound to none device and the control channel:
    ///
    /// ```no_run
    /// use hciraw::{HciChannel, HciSocket, HciSocketAddr};
    ///
    /// let addr = hciraw::HciSocketAddr::new(None, HciChannel::Control);
    /// let socket = hciraw::HciSocket::bind(addr).unwrap();
    /// ```
    ///
    /// Creates HCI raw socket bound to the first Bluetooth controller and the
    /// raw channel.
    ///
    /// ```no_run
    /// use hciraw::{HciChannel, HciSocket, HciSocketAddr};
    ///
    /// let addr = HciSocketAddr::new(Some(0), HciChannel::Raw);
    /// let socket = HciSocket::bind(addr).unwrap();
    /// ```
    pub fn bind<A: ToHciSocketAddr>(addr: A) -> io::Result<HciSocket> {
        match bt_impl::HciSocket::bind(addr.to_socket_addr()) {
            Ok(hrs) => Ok(HciSocket(hrs)),
            Err(e) => Err(e),
        }
    }

    /// Sends data on the socket to the HciDevice and using the
    /// HciChannel the socket is bond to.
    ///
    /// # Return
    ///
    /// On success the number of bytes sent, error otherwise.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use hciraw::{HciChannel, HciSocket, HciSocketAddr};
    ///
    /// let addr = HciSocketAddr::new(None, HciChannel::Control);
    /// let socket = HciSocket::bind(addr).expect("Error binding the socket");
    ///
    /// let mut buf = [0; 128];
    /// use hciraw;
    ///
    /// let data: [u8; 6] = [0x01, 0x00, 0xff, 0xff, 0x00, 0x00];
    /// let retval = socket.send(&data).unwrap();
    /// ```
    ///
    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.send(buf)
    }

    /// Receives a single message on the socket from the HciDevice and using the
    /// HciChannel the socket is bond to.
    ///
    /// It must be called with valid byte array `buf` of sufficient size to
    /// hold the data packet. Bytes that do not fit into the `buf` are
    /// discarded.
    ///
    /// # Return
    ///
    /// On success the number of bytes read, error otherwise.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use hciraw::{HciChannel, HciSocket, HciSocketAddr};
    ///
    /// let addr = HciSocketAddr::new(None, HciChannel::Control);
    /// let socket = HciSocket::bind(addr).expect("Error binding the socket");
    ///
    /// let mut rbuf = vec![0;128];
    /// match socket.recv(rbuf.as_mut_slice()) {
    ///     Ok(n) => println!("Recv {} bytes", n),
    ///     Err(e) => println!("Failed to read data {}", e),
    /// }
    /// ```
    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.recv(buf)
    }
}