stm32wb_hci/host/
uart.rs

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