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
//! Implementation of the HCI that includes the packet ID byte in the header.
use byteorder::{ByteOrder, LittleEndian};
use crate::vendor::stm32wb::{event::Stm32Wb5xEvent, Stm32Wb5xError};
const PACKET_TYPE_HCI_COMMAND: u8 = 0x01;
// const PACKET_TYPE_ACL_DATA: u8 = 0x02;
// const PACKET_TYPE_SYNC_DATA: u8 = 0x03;
const PACKET_TYPE_HCI_EVENT: u8 = 0x04;
/// Potential errors from reading or writing packets to the controller.
///
/// Must be specialized both for communication errors (`E`) and vendor-specific errors (`VE`).
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<VE> {
/// The host expected the controller to begin a packet, but the next byte is not a valid packet
/// type byte. Contains the value of the byte.
BadPacketType(u8),
/// There was an error deserializing an event. Contains the underlying error.
BLE(crate::event::Error<VE>),
}
/// Packet types that may be read from the controller.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Packet<Vendor>
where
Vendor: crate::event::VendorEvent,
{
// AclData(AclData),
// SyncData(SyncData),
/// The HCI Event Packet is used by the Controller to notify the Host when events
/// occur. The event is specialized to support vendor-specific events.
Event(crate::Event<Vendor>),
}
/// Header for HCI Commands.
pub struct CommandHeader {
opcode: crate::opcode::Opcode,
param_len: u8,
}
/// Trait for reading packets from the controller.
///
/// Implementors must also implement [`crate::host::HostHci`], which provides all of the functions to
/// write commands to the controller. This trait adds the ability to read packets back from the
/// controller.
///
/// Must be specialized for communication errors (`E`), vendor-specific events (`Vendor`), and
/// vendor-specific errors (`VE`).
pub trait UartHci: super::HostHci {
/// Reads and returns a packet from the controller. Consumes exactly enough bytes to read the
/// next packet including its header.
///
/// # Errors
///
/// - Returns [`Error::BadPacketType`] if the next byte is not a valid
/// packet type.
/// - Returns [`Error::BLE`] if there is an error deserializing the
/// packet (such as a mismatch between the packet length and the expected length of the
/// event). See [`crate::event::Error`] for possible values of `e`.
/// - Returns [`Error::Comm`] if there is an error reading from the
/// controller.
async fn read(&mut self) -> Result<Packet<Stm32Wb5xEvent>, Error<Stm32Wb5xError>>;
}
impl super::HciHeader for CommandHeader {
const HEADER_LENGTH: usize = 4;
fn new(opcode: crate::opcode::Opcode, param_len: usize) -> CommandHeader {
CommandHeader {
opcode,
param_len: param_len as u8,
}
}
fn copy_into_slice(&self, buffer: &mut [u8]) {
buffer[0] = PACKET_TYPE_HCI_COMMAND;
LittleEndian::write_u16(&mut buffer[1..=2], self.opcode.0);
buffer[3] = self.param_len;
}
}
impl<T> UartHci for T
where
T: crate::Controller,
{
async fn read(&mut self) -> Result<Packet<Stm32Wb5xEvent>, Error<Stm32Wb5xError>> {
const MAX_EVENT_LENGTH: usize = 255;
const PACKET_HEADER_LENGTH: usize = 1;
const EVENT_PACKET_HEADER_LENGTH: usize = 3;
const PARAM_LEN_BYTE: usize = 2;
let mut packet = [0u8; MAX_EVENT_LENGTH];
self.controller_read_into(&mut packet).await;
let packet_type = packet[0];
match packet_type {
PACKET_TYPE_HCI_EVENT => {
let param_len = packet[PARAM_LEN_BYTE] as usize;
let mut buf = [0; MAX_EVENT_LENGTH + EVENT_PACKET_HEADER_LENGTH];
buf[..EVENT_PACKET_HEADER_LENGTH + param_len]
.copy_from_slice(&packet[..EVENT_PACKET_HEADER_LENGTH + param_len]);
Ok(Packet::Event(
crate::event::Event::new(crate::event::Packet(
&buf[PACKET_HEADER_LENGTH..EVENT_PACKET_HEADER_LENGTH + param_len],
))
.map_err(Error::BLE)?,
))
}
x => Err(Error::BadPacketType(x)),
}
}
}