esp_wifi/ble/controller/
mod.rs

1use embedded_io::{Error, ErrorType, Read, Write};
2
3use super::{read_hci, read_next, send_hci};
4use crate::EspWifiController;
5
6/// A blocking HCI connector
7pub struct BleConnector<'d> {
8    _device: crate::hal::peripherals::BT<'d>,
9}
10
11impl Drop for BleConnector<'_> {
12    fn drop(&mut self) {
13        crate::ble::ble_deinit();
14    }
15}
16
17impl<'d> BleConnector<'d> {
18    pub fn new(
19        _init: &'d EspWifiController<'d>,
20        device: crate::hal::peripherals::BT<'d>,
21    ) -> BleConnector<'d> {
22        crate::ble::ble_init();
23
24        Self { _device: device }
25    }
26
27    pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
28        Ok(read_next(buf))
29    }
30}
31
32#[derive(Debug)]
33pub enum BleConnectorError {
34    Unknown,
35}
36
37impl Error for BleConnectorError {
38    fn kind(&self) -> embedded_io::ErrorKind {
39        embedded_io::ErrorKind::Other
40    }
41}
42
43impl ErrorType for BleConnector<'_> {
44    type Error = BleConnectorError;
45}
46
47impl Read for BleConnector<'_> {
48    fn read(&mut self, mut buf: &mut [u8]) -> Result<usize, Self::Error> {
49        let mut total = 0;
50        while !buf.is_empty() {
51            let len = read_hci(buf);
52            if len == 0 {
53                break;
54            }
55
56            buf = &mut buf[len..];
57            total += len;
58        }
59        Ok(total)
60    }
61}
62
63impl Write for BleConnector<'_> {
64    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
65        for b in buf {
66            send_hci(&[*b]);
67        }
68        Ok(buf.len())
69    }
70
71    fn flush(&mut self) -> Result<(), Self::Error> {
72        // nothing to do
73        Ok(())
74    }
75}
76
77/// Async Interface
78pub(crate) mod asynch {
79    use core::task::Poll;
80
81    use bt_hci::{
82        ControllerToHostPacket,
83        FromHciBytes,
84        HostToControllerPacket,
85        WriteHci,
86        transport::{Transport, WithIndicator},
87    };
88    use esp_hal::asynch::AtomicWaker;
89
90    use super::*;
91    use crate::ble::have_hci_read_data;
92
93    static HCI_WAKER: AtomicWaker = AtomicWaker::new();
94
95    pub(crate) fn hci_read_data_available() {
96        HCI_WAKER.wake();
97    }
98
99    impl embedded_io_async::Read for BleConnector<'_> {
100        async fn read(&mut self, mut buf: &mut [u8]) -> Result<usize, BleConnectorError> {
101            if buf.is_empty() {
102                return Ok(0);
103            }
104
105            let mut total = 0;
106            if !have_hci_read_data() {
107                HciReadyEventFuture.await;
108            }
109            while !buf.is_empty() {
110                let len = read_hci(buf);
111                if len == 0 {
112                    break;
113                }
114
115                buf = &mut buf[len..];
116                total += len;
117            }
118            Ok(total)
119        }
120    }
121
122    impl embedded_io_async::Write for BleConnector<'_> {
123        async fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
124            send_hci(buf);
125            Ok(buf.len())
126        }
127
128        async fn flush(&mut self) -> Result<(), BleConnectorError> {
129            // nothing to do
130            Ok(())
131        }
132    }
133
134    #[must_use = "futures do nothing unless you `.await` or poll them"]
135    pub(crate) struct HciReadyEventFuture;
136
137    impl core::future::Future for HciReadyEventFuture {
138        type Output = ();
139
140        fn poll(
141            self: core::pin::Pin<&mut Self>,
142            cx: &mut core::task::Context<'_>,
143        ) -> Poll<Self::Output> {
144            HCI_WAKER.register(cx.waker());
145
146            if have_hci_read_data() {
147                Poll::Ready(())
148            } else {
149                Poll::Pending
150            }
151        }
152    }
153
154    fn parse_hci(data: &[u8]) -> Result<Option<ControllerToHostPacket<'_>>, BleConnectorError> {
155        match ControllerToHostPacket::from_hci_bytes_complete(data) {
156            Ok(p) => Ok(Some(p)),
157            Err(e) => {
158                if e == bt_hci::FromHciBytesError::InvalidSize {
159                    use bt_hci::{PacketKind, event::EventPacketHeader};
160
161                    // Some controllers emit a suprious command complete event at startup.
162                    let (kind, data) =
163                        PacketKind::from_hci_bytes(data).map_err(|_| BleConnectorError::Unknown)?;
164                    if kind == PacketKind::Event {
165                        let (header, _) = EventPacketHeader::from_hci_bytes(data)
166                            .map_err(|_| BleConnectorError::Unknown)?;
167                        const COMMAND_COMPLETE: u8 = 0x0E;
168                        if header.code == COMMAND_COMPLETE && header.params_len < 4 {
169                            return Ok(None);
170                        }
171                    }
172                }
173                warn!("[hci] error parsing packet: {:?}", e);
174
175                Err(BleConnectorError::Unknown)
176            }
177        }
178    }
179
180    impl Transport for BleConnector<'_> {
181        /// Read a complete HCI packet into the rx buffer
182        async fn read<'a>(
183            &self,
184            rx: &'a mut [u8],
185        ) -> Result<ControllerToHostPacket<'a>, Self::Error> {
186            loop {
187                if !have_hci_read_data() {
188                    HciReadyEventFuture.await;
189                }
190
191                // Workaround for borrow checker.
192                // Safety: we only return a reference to x once, if parsing is successful.
193                let rx =
194                    unsafe { &mut *core::ptr::slice_from_raw_parts_mut(rx.as_mut_ptr(), rx.len()) };
195
196                let len = crate::ble::read_next(rx);
197                if let Some(packet) = parse_hci(&rx[..len])? {
198                    return Ok(packet);
199                }
200            }
201        }
202
203        /// Write a complete HCI packet from the tx buffer
204        async fn write<T: HostToControllerPacket>(&self, val: &T) -> Result<(), Self::Error> {
205            let mut buf: [u8; 259] = [0; 259];
206            let w = WithIndicator::new(val);
207            let len = w.size();
208            w.write_hci(&mut buf[..])
209                .map_err(|_| BleConnectorError::Unknown)?;
210            send_hci(&buf[..len]);
211            Ok(())
212        }
213    }
214}