bluetooth_hci/host/
uart.rs

1//! Implementation of the HCI that includes the packet ID byte in the header.
2
3extern crate nb;
4
5use byteorder::{ByteOrder, LittleEndian};
6
7const PACKET_TYPE_HCI_COMMAND: u8 = 0x01;
8// const PACKET_TYPE_ACL_DATA: u8 = 0x02;
9// const PACKET_TYPE_SYNC_DATA: u8 = 0x03;
10const PACKET_TYPE_HCI_EVENT: u8 = 0x04;
11
12/// Potential errors from reading or writing packets to the controller.
13///
14/// Must be specialized both for communication errors (`E`) and vendor-specific errors (`VE`).
15#[derive(Copy, Clone, Debug, PartialEq)]
16pub enum Error<E, VE> {
17    /// The host expected the controller to begin a packet, but the next byte is not a valid packet
18    /// type byte. Contains the value of the byte.
19    BadPacketType(u8),
20    /// There was an error deserializing an event. Contains the underlying error.
21    BLE(crate::event::Error<VE>),
22    /// There was a communication error. Contains the underlying error.
23    Comm(E),
24}
25
26/// Packet types that may be read from the controller.
27#[derive(Clone, Debug)]
28pub enum Packet<Vendor>
29where
30    Vendor: crate::event::VendorEvent,
31{
32    // AclData(AclData),
33    // SyncData(SyncData),
34    /// The HCI Event Packet is used by the Controller to notify the Host when events
35    /// occur. The event is specialized to support vendor-specific events.
36    Event(crate::Event<Vendor>),
37}
38
39/// Header for HCI Commands.
40pub struct CommandHeader {
41    opcode: crate::opcode::Opcode,
42    param_len: u8,
43}
44
45/// Trait for reading packets from the controller.
46///
47/// Implementors must also implement [`crate::host::Hci`], which provides all of the functions to
48/// write commands to the controller. This trait adds the ability to read packets back from the
49/// controller.
50///
51/// Must be specialized for communication errors (`E`), vendor-specific events (`Vendor`), and
52/// vendor-specific errors (`VE`).
53pub trait Hci<E, Vendor, VE>: super::Hci<E> {
54    /// Reads and returns a packet from the controller. Consumes exactly enough bytes to read the
55    /// next packet including its header.
56    ///
57    /// # Errors
58    ///
59    /// - Returns [`nb::Error::WouldBlock`] if the controller does not have enough bytes available
60    ///   to read the full packet right now.
61    /// - Returns [`nb::Error::Other`]`(`[`Error::BadPacketType`]`)` if the next byte is not a valid
62    ///   packet type.
63    /// - Returns [`nb::Error::Other`]`(`[`Error::BLE`]`)` if there is an error deserializing the
64    ///   packet (such as a mismatch between the packet length and the expected length of the
65    ///   event). See [`crate::event::Error`] for possible values of `e`.
66    /// - Returns [`nb::Error::Other`]`(`[`Error::Comm`]`)` if there is an error reading from the
67    ///   controller.
68    fn read(&mut self) -> nb::Result<Packet<Vendor>, Error<E, VE>>
69    where
70        Vendor: crate::event::VendorEvent<Error = VE>;
71}
72
73impl super::HciHeader for CommandHeader {
74    const HEADER_LENGTH: usize = 4;
75
76    fn new(opcode: crate::opcode::Opcode, param_len: usize) -> CommandHeader {
77        CommandHeader {
78            opcode,
79            param_len: param_len as u8,
80        }
81    }
82
83    fn copy_into_slice(&self, buffer: &mut [u8]) {
84        buffer[0] = PACKET_TYPE_HCI_COMMAND;
85        LittleEndian::write_u16(&mut buffer[1..=2], self.opcode.0);
86        buffer[3] = self.param_len;
87    }
88}
89
90fn rewrap_error<E, VE>(e: nb::Error<E>) -> nb::Error<Error<E, VE>> {
91    match e {
92        nb::Error::WouldBlock => nb::Error::WouldBlock,
93        nb::Error::Other(err) => nb::Error::Other(Error::Comm(err)),
94    }
95}
96
97fn read_event<E, T, Vendor, VE>(
98    controller: &mut T,
99) -> nb::Result<crate::Event<Vendor>, Error<E, VE>>
100where
101    T: crate::Controller<Error = E>,
102    Vendor: crate::event::VendorEvent<Error = VE>,
103{
104    const MAX_EVENT_LENGTH: usize = 255;
105    const PACKET_HEADER_LENGTH: usize = 1;
106    const EVENT_PACKET_HEADER_LENGTH: usize = 3;
107    const PARAM_LEN_BYTE: usize = 2;
108
109    let param_len = controller.peek(PARAM_LEN_BYTE).map_err(rewrap_error)? as usize;
110
111    let mut buf = [0; MAX_EVENT_LENGTH + EVENT_PACKET_HEADER_LENGTH];
112    controller
113        .read_into(&mut buf[..EVENT_PACKET_HEADER_LENGTH + param_len])
114        .map_err(rewrap_error)?;
115
116    crate::event::Event::new(crate::event::Packet(
117        &buf[PACKET_HEADER_LENGTH..EVENT_PACKET_HEADER_LENGTH + param_len],
118    ))
119    .map_err(|e| nb::Error::Other(Error::BLE(e)))
120}
121
122impl<E, Vendor, VE, T> Hci<E, Vendor, VE> for T
123where
124    T: crate::Controller<Error = E, Header = CommandHeader>,
125{
126    fn read(&mut self) -> nb::Result<Packet<Vendor>, Error<E, VE>>
127    where
128        Vendor: crate::event::VendorEvent<Error = VE>,
129    {
130        match self.peek(0).map_err(rewrap_error)? {
131            PACKET_TYPE_HCI_EVENT => Ok(Packet::Event(read_event(self)?)),
132            x => Err(nb::Error::Other(Error::BadPacketType(x))),
133        }
134    }
135}