bluetooth_hci/host/event_link.rs
1//! Implementation of the HCI that only supports reading events from the controller.
2//!
3//! This was originally written just based on wording from the Bluetooth spec (version 5.0, Vol 4,
4//! Part A, section 2), emphasis added:
5//!
6//! > Therefore, *if* the HCI packets are sent via a common physical interface, a HCI
7//! > packet indicator has to be added according to Table 2.1 below.
8//!
9//! However, there don't seem to be any implementations where the HCI packets are _not_ sent "via a
10//! common physical interface", so this module may be unnecessary.
11
12extern crate nb;
13
14/// Potential errors from reading events from the controller.
15#[derive(Copy, Clone, Debug)]
16pub enum Error<E, VError> {
17 /// There was an error deserializing an event. Contains the underlying error.
18 BLE(crate::event::Error<VError>),
19 /// There was a communication error. Contains the underlying error.
20 Comm(E),
21}
22
23/// Dummy struct used to specialize [`super::Hci`]. Since the [`Hci`] does not support sending
24/// commands, we do not need a real header struct.
25pub struct NoCommands;
26
27/// Trait for reading events from the controller. Since this trait should only be used when events
28/// are sent by a different physical link than commands, it does not need to implement
29/// [`crate::host::Hci`].
30///
31/// Must be specialized for communication errors (`E`), vendor-specific events (`Vendor`), and
32/// vendor-specific errors (`VE`).
33///
34/// Peeks ahead 2 bytes into the stream to read the length of the parameters for the next event.
35///
36/// # Errors
37///
38/// - Returns [`nb::Error::WouldBlock`] if the controller does not have enough bytes to read an
39/// event.
40/// - Returns [`nb::Error::Other`]`(`[`Error::BLE`]`)` if there is an error deserializing the packet
41/// (such as a mismatch between the packet length and the expected length of the event). See
42/// [`crate::event::Error`] for possible values of `e`.
43/// - Returns [`nb::Error::Other`]`(`[`Error::Comm`]`)` if there is an error reading from the
44/// controller.
45pub trait Hci<E, Vendor, VE> {
46 /// Reads and returns an event from the controller. Consumes exactly enough bytes to read the
47 /// next event including its header.
48 ///
49 /// # Errors
50 ///
51 /// - Returns [`nb::Error::WouldBlock`] if the controller does not have enough bytes available
52 /// to read the full event right now.
53 /// - Returns [`nb::Error::Other`]`(`[`Error::BLE`]`)` if there is an error deserializing the
54 /// packet (such as a mismatch between the packet length and the expected length of the
55 /// event). See [`crate::event::Error`] for possible values of `e`.
56 /// - Returns [`nb::Error::Other`]`(`[`Error::Comm`]`)` if there is an error reading from the
57 /// controller.
58 fn read(&mut self) -> nb::Result<crate::Event<Vendor>, Error<E, VE>>
59 where
60 Vendor: crate::event::VendorEvent<Error = VE>;
61}
62
63impl super::HciHeader for NoCommands {
64 const HEADER_LENGTH: usize = 3;
65
66 fn new(_opcode: crate::opcode::Opcode, _param_len: usize) -> NoCommands {
67 NoCommands
68 }
69
70 fn copy_into_slice(&self, _buffer: &mut [u8]) {}
71}
72
73fn rewrap_error<E, VE>(e: nb::Error<E>) -> nb::Error<Error<E, VE>> {
74 match e {
75 nb::Error::WouldBlock => nb::Error::WouldBlock,
76 nb::Error::Other(err) => nb::Error::Other(Error::Comm(err)),
77 }
78}
79
80impl<E, Vendor, VE, T> Hci<E, Vendor, VE> for T
81where
82 T: crate::Controller<Error = E, Header = NoCommands>,
83{
84 fn read(&mut self) -> nb::Result<crate::Event<Vendor>, Error<E, VE>>
85 where
86 Vendor: crate::event::VendorEvent<Error = VE>,
87 {
88 const MAX_EVENT_LENGTH: usize = 255;
89 const EVENT_HEADER_LENGTH: usize = 2;
90 const PARAM_LEN_BYTE: usize = 1;
91
92 let param_len = self.peek(PARAM_LEN_BYTE).map_err(rewrap_error)? as usize;
93
94 let mut buf = [0; MAX_EVENT_LENGTH + EVENT_HEADER_LENGTH];
95 self.read_into(&mut buf[..EVENT_HEADER_LENGTH + param_len])
96 .map_err(rewrap_error)?;
97
98 crate::Event::new(crate::event::Packet(
99 &buf[..EVENT_HEADER_LENGTH + param_len],
100 ))
101 .map_err(|e| nb::Error::Other(Error::BLE(e)))
102 }
103}