esp_radio/ble/controller/
mod.rs

1use core::task::Poll;
2
3use bt_hci::{
4    ControllerToHostPacket,
5    FromHciBytes,
6    FromHciBytesError,
7    HostToControllerPacket,
8    WriteHci,
9    transport::{Transport, WithIndicator},
10};
11use esp_hal::asynch::AtomicWaker;
12use esp_phy::PhyInitGuard;
13
14use crate::{
15    Controller,
16    ble::{Config, InvalidConfigError, have_hci_read_data, read_hci, read_next, send_hci},
17};
18
19/// A blocking HCI connector
20#[instability::unstable]
21pub struct BleConnector<'d> {
22    _phy_init_guard: PhyInitGuard<'d>,
23    _device: crate::hal::peripherals::BT<'d>,
24}
25impl Drop for BleConnector<'_> {
26    fn drop(&mut self) {
27        crate::ble::ble_deinit();
28    }
29}
30impl<'d> BleConnector<'d> {
31    /// Create and init a new BLE connector.
32    #[instability::unstable]
33    pub fn new(
34        _init: &'d Controller<'d>,
35        device: crate::hal::peripherals::BT<'d>,
36        config: Config,
37    ) -> Result<BleConnector<'d>, InvalidConfigError> {
38        config.validate()?;
39        Ok(Self {
40            _phy_init_guard: crate::ble::ble_init(&config),
41            _device: device,
42        })
43    }
44
45    /// Read the next HCI packet from the BLE controller.
46    #[instability::unstable]
47    pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
48        Ok(read_next(buf))
49    }
50
51    /// Read from HCI.
52    #[instability::unstable]
53    pub fn read(&mut self, mut buf: &mut [u8]) -> Result<usize, BleConnectorError> {
54        let mut total = 0;
55        while !buf.is_empty() {
56            let len = read_hci(buf);
57            if len == 0 {
58                break;
59            }
60
61            buf = &mut buf[len..];
62            total += len;
63        }
64        Ok(total)
65    }
66
67    /// Read from HCI.
68    #[instability::unstable]
69    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
70        if buf.is_empty() {
71            return Ok(0);
72        }
73
74        if !have_hci_read_data() {
75            HciReadyEventFuture.await;
76        }
77
78        self.read(buf)
79    }
80
81    /// Write to HCI.
82    #[instability::unstable]
83    pub fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
84        for b in buf {
85            send_hci(&[*b]);
86        }
87        Ok(buf.len())
88    }
89}
90
91#[derive(Debug)]
92#[cfg_attr(feature = "defmt", derive(defmt::Format))]
93/// Error type for the BLE connector.
94#[instability::unstable]
95pub enum BleConnectorError {
96    Unknown,
97}
98
99impl embedded_io_06::Error for BleConnectorError {
100    fn kind(&self) -> embedded_io_06::ErrorKind {
101        embedded_io_06::ErrorKind::Other
102    }
103}
104
105impl embedded_io_07::Error for BleConnectorError {
106    fn kind(&self) -> embedded_io_07::ErrorKind {
107        embedded_io_07::ErrorKind::Other
108    }
109}
110
111impl core::error::Error for BleConnectorError {}
112
113impl core::fmt::Display for BleConnectorError {
114    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
115        match self {
116            BleConnectorError::Unknown => write!(f, "Unknown BLE error occured"),
117        }
118    }
119}
120
121impl embedded_io_06::ErrorType for BleConnector<'_> {
122    type Error = BleConnectorError;
123}
124
125impl embedded_io_06::Read for BleConnector<'_> {
126    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
127        self.read(buf)
128    }
129}
130
131impl embedded_io_06::Write for BleConnector<'_> {
132    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
133        self.write(buf)
134    }
135
136    fn flush(&mut self) -> Result<(), Self::Error> {
137        // nothing to do
138        Ok(())
139    }
140}
141
142impl embedded_io_07::ErrorType for BleConnector<'_> {
143    type Error = BleConnectorError;
144}
145
146impl embedded_io_07::Read for BleConnector<'_> {
147    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
148        self.read(buf)
149    }
150}
151
152impl embedded_io_07::Write for BleConnector<'_> {
153    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
154        self.write(buf)
155    }
156
157    fn flush(&mut self) -> Result<(), Self::Error> {
158        // nothing to do
159        Ok(())
160    }
161}
162
163static HCI_WAKER: AtomicWaker = AtomicWaker::new();
164
165pub(crate) fn hci_read_data_available() {
166    HCI_WAKER.wake();
167}
168
169impl embedded_io_async_06::Read for BleConnector<'_> {
170    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
171        self.read_async(buf).await
172    }
173}
174
175impl embedded_io_async_06::Write for BleConnector<'_> {
176    async fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
177        send_hci(buf);
178        Ok(buf.len())
179    }
180
181    async fn flush(&mut self) -> Result<(), BleConnectorError> {
182        // nothing to do
183        Ok(())
184    }
185}
186
187impl embedded_io_async_07::Read for BleConnector<'_> {
188    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
189        self.read_async(buf).await
190    }
191}
192
193impl embedded_io_async_07::Write for BleConnector<'_> {
194    async fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
195        send_hci(buf);
196        Ok(buf.len())
197    }
198
199    async fn flush(&mut self) -> Result<(), BleConnectorError> {
200        // nothing to do
201        Ok(())
202    }
203}
204
205impl From<FromHciBytesError> for BleConnectorError {
206    fn from(_e: FromHciBytesError) -> Self {
207        BleConnectorError::Unknown
208    }
209}
210
211#[must_use = "futures do nothing unless you `.await` or poll them"]
212pub(crate) struct HciReadyEventFuture;
213
214impl core::future::Future for HciReadyEventFuture {
215    type Output = ();
216
217    fn poll(
218        self: core::pin::Pin<&mut Self>,
219        cx: &mut core::task::Context<'_>,
220    ) -> Poll<Self::Output> {
221        HCI_WAKER.register(cx.waker());
222
223        if have_hci_read_data() {
224            Poll::Ready(())
225        } else {
226            Poll::Pending
227        }
228    }
229}
230
231fn parse_hci(data: &[u8]) -> Result<Option<ControllerToHostPacket<'_>>, BleConnectorError> {
232    match ControllerToHostPacket::from_hci_bytes_complete(data) {
233        Ok(p) => Ok(Some(p)),
234        Err(e) => {
235            warn!("[hci] error parsing packet: {:?}", e);
236            Err(BleConnectorError::Unknown)
237        }
238    }
239}
240
241impl Transport for BleConnector<'_> {
242    /// Read a complete HCI packet into the rx buffer
243    async fn read<'a>(&self, rx: &'a mut [u8]) -> Result<ControllerToHostPacket<'a>, Self::Error> {
244        loop {
245            if !have_hci_read_data() {
246                HciReadyEventFuture.await;
247            }
248
249            // Workaround for borrow checker.
250            // Safety: we only return a reference to x once, if parsing is successful.
251            let rx =
252                unsafe { &mut *core::ptr::slice_from_raw_parts_mut(rx.as_mut_ptr(), rx.len()) };
253
254            let len = crate::ble::read_next(rx);
255            if let Some(packet) = parse_hci(&rx[..len])? {
256                return Ok(packet);
257            }
258        }
259    }
260
261    /// Write a complete HCI packet from the tx buffer
262    async fn write<T: HostToControllerPacket>(&self, val: &T) -> Result<(), Self::Error> {
263        let mut buf: [u8; 259] = [0; 259];
264        let w = WithIndicator::new(val);
265        let len = w.size();
266        w.write_hci(&mut buf[..])
267            .map_err(|_| BleConnectorError::Unknown)?;
268        send_hci(&buf[..len]);
269        Ok(())
270    }
271}