esp_radio/ble/controller/
mod.rs1use alloc::boxed::Box;
3use core::{future::Future, task::Poll};
4
5use bt_hci::{
6 ControllerToHostPacket,
7 FromHciBytes,
8 FromHciBytesError,
9 HostToControllerPacket,
10 WriteHci,
11};
12use bt_hci_transport::{PacketKind, PacketToController, PacketToHost};
13use docsplay::Display;
14use esp_phy::PhyInitGuard;
15
16use crate::{
17 RadioRefGuard,
18 asynch::AtomicWaker,
19 ble::{
20 Config,
21 InvalidConfigError,
22 have_hci_packet,
23 have_hci_read_data,
24 read_hci,
25 read_next,
26 send_hci,
27 send_hci_async,
28 take_next,
29 },
30};
31
32#[derive(Display, Debug, Copy, Clone, Eq, PartialEq, Hash)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34pub enum BleInitError {
36 Config(InvalidConfigError),
38}
39
40impl core::error::Error for BleInitError {}
41
42impl From<InvalidConfigError> for BleInitError {
44 fn from(err: InvalidConfigError) -> Self {
45 BleInitError::Config(err)
46 }
47}
48
49#[instability::unstable]
51pub struct BleConnector<'d> {
52 _phy_init_guard: PhyInitGuard<'d>,
53 _device: crate::hal::peripherals::BT<'d>,
54 _guard: RadioRefGuard,
55}
56
57impl Drop for BleConnector<'_> {
58 fn drop(&mut self) {
59 crate::ble::ble_deinit();
60 crate::ble::clear_bt_state();
61 }
62}
63impl<'d> BleConnector<'d> {
64 #[instability::unstable]
66 pub fn new(
67 device: crate::hal::peripherals::BT<'d>,
68 config: Config,
69 ) -> Result<BleConnector<'d>, BleInitError> {
70 let _guard = RadioRefGuard::new();
71
72 config.validate()?;
73
74 Ok(Self {
75 _phy_init_guard: crate::ble::ble_init(&config),
76 _device: device,
77 _guard,
78 })
79 }
80
81 #[instability::unstable]
83 pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
84 Ok(read_next(buf))
85 }
86
87 #[instability::unstable]
89 pub fn read(&mut self, mut buf: &mut [u8]) -> Result<usize, BleConnectorError> {
90 let mut total = 0;
91 while !buf.is_empty() {
92 let len = read_hci(buf);
93 if len == 0 {
94 break;
95 }
96
97 buf = &mut buf[len..];
98 total += len;
99 }
100 Ok(total)
101 }
102
103 #[instability::unstable]
105 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
106 if buf.is_empty() {
107 return Ok(0);
108 }
109
110 HciAnyDataReadyEventFuture.await;
111
112 self.read(buf)
113 }
114
115 #[instability::unstable]
119 pub fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
120 Ok(send_hci(buf))
121 }
122
123 #[instability::unstable]
127 pub async fn write_async(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
128 Ok(send_hci_async(buf).await)
129 }
130}
131
132#[derive(Display, Debug, Copy, Clone, Eq, PartialEq, Hash)]
133#[cfg_attr(feature = "defmt", derive(defmt::Format))]
134#[instability::unstable]
136pub enum BleConnectorError {
137 Unknown,
139}
140
141impl embedded_io_06::Error for BleConnectorError {
142 fn kind(&self) -> embedded_io_06::ErrorKind {
143 embedded_io_06::ErrorKind::Other
144 }
145}
146
147impl embedded_io_07::Error for BleConnectorError {
148 fn kind(&self) -> embedded_io_07::ErrorKind {
149 embedded_io_07::ErrorKind::Other
150 }
151}
152
153impl core::error::Error for BleConnectorError {}
154
155impl embedded_io_06::ErrorType for BleConnector<'_> {
156 type Error = BleConnectorError;
157}
158
159impl embedded_io_06::Read for BleConnector<'_> {
160 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
161 self.read(buf)
162 }
163}
164
165impl embedded_io_06::Write for BleConnector<'_> {
166 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
167 self.write(buf)
168 }
169
170 fn flush(&mut self) -> Result<(), Self::Error> {
171 Ok(())
173 }
174}
175
176impl embedded_io_07::ErrorType for BleConnector<'_> {
177 type Error = BleConnectorError;
178}
179
180impl embedded_io_07::Read for BleConnector<'_> {
181 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
182 self.read(buf)
183 }
184}
185
186impl embedded_io_07::Write for BleConnector<'_> {
187 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
188 self.write(buf)
189 }
190
191 fn flush(&mut self) -> Result<(), Self::Error> {
192 Ok(())
194 }
195}
196
197static HCI_WAKER: AtomicWaker = AtomicWaker::new();
198
199pub(crate) fn hci_read_data_available() {
200 HCI_WAKER.wake();
201}
202
203impl embedded_io_async_06::Read for BleConnector<'_> {
204 fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize, BleConnectorError>> {
205 self.read_async(buf)
206 }
207}
208
209impl embedded_io_async_06::Write for BleConnector<'_> {
210 async fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
211 self.write_async(buf).await
212 }
213
214 async fn flush(&mut self) -> Result<(), BleConnectorError> {
215 Ok(())
217 }
218}
219
220impl embedded_io_async_07::Read for BleConnector<'_> {
221 fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize, BleConnectorError>> {
222 self.read_async(buf)
223 }
224}
225
226impl embedded_io_async_07::Write for BleConnector<'_> {
227 async fn write(&mut self, buf: &[u8]) -> Result<usize, BleConnectorError> {
228 self.write_async(buf).await
229 }
230
231 async fn flush(&mut self) -> Result<(), BleConnectorError> {
232 Ok(())
234 }
235}
236
237impl From<FromHciBytesError> for BleConnectorError {
238 fn from(_e: FromHciBytesError) -> Self {
239 BleConnectorError::Unknown
240 }
241}
242
243pub(crate) struct HciAnyDataReadyEventFuture;
245
246impl core::future::Future for HciAnyDataReadyEventFuture {
247 type Output = ();
248
249 fn poll(
250 self: core::pin::Pin<&mut Self>,
251 cx: &mut core::task::Context<'_>,
252 ) -> Poll<Self::Output> {
253 HCI_WAKER.register(cx.waker());
254
255 if have_hci_read_data() {
256 Poll::Ready(())
257 } else {
258 Poll::Pending
259 }
260 }
261}
262
263pub(crate) struct HciPacketReadyEventFuture;
265
266impl core::future::Future for HciPacketReadyEventFuture {
267 type Output = ();
268
269 fn poll(
270 self: core::pin::Pin<&mut Self>,
271 cx: &mut core::task::Context<'_>,
272 ) -> Poll<Self::Output> {
273 HCI_WAKER.register(cx.waker());
274
275 if have_hci_packet() {
276 Poll::Ready(())
277 } else {
278 Poll::Pending
279 }
280 }
281}
282
283struct HciWriter;
288
289impl embedded_io_07::ErrorType for HciWriter {
290 type Error = BleConnectorError;
291}
292
293impl embedded_io_async_07::Write for HciWriter {
294 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
295 Ok(send_hci_async(buf).await)
296 }
297
298 async fn flush(&mut self) -> Result<(), Self::Error> {
299 Ok(())
301 }
302}
303
304impl<E: embedded_io_07::Error> From<bt_hci_transport::ReadHciError<E>> for BleConnectorError {
305 fn from(_e: bt_hci_transport::ReadHciError<E>) -> Self {
306 BleConnectorError::Unknown
307 }
308}
309
310fn parse_hci(data: &[u8]) -> Result<ControllerToHostPacket<'_>, BleConnectorError> {
311 match ControllerToHostPacket::from_hci_bytes_complete(data) {
312 Ok(p) => Ok(p),
313 Err(e) => {
314 warn!("[hci] error parsing packet: {:?}", e);
315 Err(BleConnectorError::Unknown)
316 }
317 }
318}
319
320async fn next_packet() -> Box<[u8]> {
322 loop {
323 HciPacketReadyEventFuture.await;
324
325 if let Some(packet) = take_next() {
326 return packet;
327 }
328 }
329}
330
331impl bt_hci::transport::Transport for BleConnector<'_> {
332 async fn read<'a>(&self, rx: &'a mut [u8]) -> Result<ControllerToHostPacket<'a>, Self::Error> {
334 let rx = unsafe { &mut *core::ptr::slice_from_raw_parts_mut(rx.as_mut_ptr(), rx.len()) };
337
338 HciPacketReadyEventFuture.await;
340 let len = read_next(rx);
341 parse_hci(&rx[..len])
342 }
343
344 async fn write<T: HostToControllerPacket>(&self, val: &T) -> Result<(), Self::Error> {
346 bt_hci::transport::WithIndicator::new(val)
347 .write_hci_async(HciWriter)
348 .await
349 }
350}
351
352impl bt_hci_transport::Transport for BleConnector<'_> {
353 async fn read<'a, P: PacketToHost<'a>>(&self, rx: &'a mut [u8]) -> Result<P, Self::Error> {
355 let packet = next_packet().await;
358
359 let mut reader = &packet[..];
360 let kind = PacketKind::read(&mut reader)?;
361 Ok(P::read_hci(kind, &mut reader, rx)?)
362 }
363
364 async fn write<P: PacketToController>(&self, tx: &P) -> Result<(), Self::Error> {
366 bt_hci_transport::WithIndicator::new(tx)
367 .write_hci_async(HciWriter)
368 .await
369 }
370}