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