esp_radio/ble/controller/
mod.rs1use 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#[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 #[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 #[instability::unstable]
47 pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
48 Ok(read_next(buf))
49 }
50
51 #[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 #[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 #[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#[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 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 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 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 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 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 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 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}