1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![no_std]
4
5use core::future::Future;
6
7use bt_hci_transport::blocking::TryError;
8use bt_hci_transport::PacketToHost;
9use embedded_io::ReadExactError;
10
11mod fmt;
12
13pub mod cmd;
14pub mod controller;
15pub mod data;
16pub mod event;
17pub mod param;
18pub mod transport;
19pub use bt_hci_transport::{PacketKind, ReadHciError};
20pub use btuuid as uuid;
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25pub enum FromHciBytesError {
26 InvalidSize,
28 InvalidValue,
30}
31
32impl<E: From<FromHciBytesError>> From<FromHciBytesError> for TryError<E> {
33 fn from(value: FromHciBytesError) -> Self {
34 TryError::Error(E::from(value))
35 }
36}
37
38impl<E: embedded_io::Error> From<FromHciBytesError> for ReadHciError<E> {
39 fn from(value: FromHciBytesError) -> Self {
40 match value {
41 FromHciBytesError::InvalidSize => ReadHciError::Read(ReadExactError::UnexpectedEof),
42 FromHciBytesError::InvalidValue => ReadHciError::InvalidValue,
43 }
44 }
45}
46
47pub trait AsHciBytes {
49 fn as_hci_bytes(&self) -> &[u8];
51}
52
53pub trait FromHciBytes<'de>: Sized {
55 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError>;
57
58 fn from_hci_bytes_complete(data: &'de [u8]) -> Result<Self, FromHciBytesError> {
60 let (val, buf) = Self::from_hci_bytes(data)?;
61 if buf.is_empty() {
62 Ok(val)
63 } else {
64 Err(FromHciBytesError::InvalidSize)
65 }
66 }
67}
68
69impl<'de> FromHciBytes<'de> for PacketKind {
70 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
71 if data.is_empty() {
72 Err(FromHciBytesError::InvalidSize)
73 } else {
74 let (data, rest) = data.split_at(1);
75 match data[0] {
76 1 => Ok((PacketKind::Cmd, rest)),
77 2 => Ok((PacketKind::AclData, rest)),
78 3 => Ok((PacketKind::SyncData, rest)),
79 4 => Ok((PacketKind::Event, rest)),
80 5 => Ok((PacketKind::IsoData, rest)),
81 _ => Err(FromHciBytesError::InvalidValue),
82 }
83 }
84 }
85}
86
87pub trait ReadHci<'de>: FromHciBytes<'de> {
89 const MAX_LEN: usize;
91
92 fn read_hci<R: embedded_io::Read>(reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>>;
94
95 fn read_hci_async<R: embedded_io_async::Read>(
97 reader: R,
98 buf: &'de mut [u8],
99 ) -> impl Future<Output = Result<Self, ReadHciError<R::Error>>>;
100}
101
102pub trait WriteHci {
104 fn size(&self) -> usize;
106
107 fn write_hci<W: embedded_io::Write>(&self, writer: W) -> Result<(), W::Error>;
109
110 fn write_hci_async<W: embedded_io_async::Write>(&self, writer: W) -> impl Future<Output = Result<(), W::Error>>;
112}
113
114pub unsafe trait FixedSizeValue: Copy {
123 fn is_valid(data: &[u8]) -> bool;
127}
128
129pub unsafe trait ByteAlignedValue: FixedSizeValue {
134 fn ref_from_hci_bytes(data: &[u8]) -> Result<(&Self, &[u8]), FromHciBytesError> {
139 if data.len() < core::mem::size_of::<Self>() {
140 Err(FromHciBytesError::InvalidSize)
141 } else if !Self::is_valid(data) {
142 Err(FromHciBytesError::InvalidValue)
143 } else {
144 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
145 Ok((unsafe { &*(data.as_ptr() as *const Self) }, rest))
146 }
147 }
148}
149
150impl<T: FixedSizeValue> AsHciBytes for T {
151 fn as_hci_bytes(&self) -> &[u8] {
152 unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, core::mem::size_of::<Self>()) }
153 }
154}
155
156impl<'de, T: FixedSizeValue> FromHciBytes<'de> for T {
157 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
158 if data.len() < core::mem::size_of::<Self>() {
159 Err(FromHciBytesError::InvalidSize)
160 } else if !Self::is_valid(data) {
161 Err(FromHciBytesError::InvalidValue)
162 } else {
163 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
164 Ok((unsafe { core::ptr::read_unaligned(data.as_ptr() as *const Self) }, rest))
165 }
166 }
167}
168
169impl<'de, T: ByteAlignedValue> FromHciBytes<'de> for &'de [T] {
170 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
171 let Some((len, data)) = data.split_first() else {
172 return Err(FromHciBytesError::InvalidSize);
173 };
174
175 let len = usize::from(*len);
176 let byte_len = len * core::mem::size_of::<T>();
177 if byte_len > data.len() {
178 return Err(FromHciBytesError::InvalidSize);
179 }
180
181 let (data, rest) = data.split_at(byte_len);
182
183 if !data.chunks_exact(core::mem::size_of::<T>()).all(|x| T::is_valid(x)) {
184 return Err(FromHciBytesError::InvalidValue);
185 }
186
187 Ok((
188 unsafe { core::slice::from_raw_parts(data.as_ptr() as *const T, len) },
189 rest,
190 ))
191 }
192}
193
194impl<'de, T: FixedSizeValue> ReadHci<'de> for T {
195 const MAX_LEN: usize = core::mem::size_of::<Self>();
196
197 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
198 if buf.len() < core::mem::size_of::<Self>() {
199 Err(ReadHciError::BufferTooSmall)
200 } else {
201 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
202 reader.read_exact(buf)?;
203 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
204 }
205 }
206
207 async fn read_hci_async<R: embedded_io_async::Read>(
208 mut reader: R,
209 buf: &'de mut [u8],
210 ) -> Result<Self, ReadHciError<R::Error>> {
211 if buf.len() < core::mem::size_of::<Self>() {
212 Err(ReadHciError::BufferTooSmall)
213 } else {
214 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
215 reader.read_exact(buf).await?;
216 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
217 }
218 }
219}
220
221impl<T: FixedSizeValue> WriteHci for T {
222 #[inline(always)]
223 fn size(&self) -> usize {
224 core::mem::size_of::<Self>()
225 }
226
227 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
228 writer.write_all(self.as_hci_bytes())
229 }
230
231 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
232 writer.write_all(self.as_hci_bytes()).await
233 }
234}
235
236#[derive(Debug)]
238#[cfg_attr(feature = "defmt", derive(defmt::Format))]
239pub enum ControllerToHostPacket<'a> {
240 Acl(data::AclPacket<'a>),
242 Sync(data::SyncPacket<'a>),
244 Event(event::EventPacket<'a>),
246 Iso(data::IsoPacket<'a>),
248}
249
250impl<'a> ControllerToHostPacket<'a> {
251 pub fn kind(&self) -> PacketKind {
253 match self {
254 Self::Acl(_) => PacketKind::AclData,
255 Self::Sync(_) => PacketKind::SyncData,
256 Self::Event(_) => PacketKind::Event,
257 Self::Iso(_) => PacketKind::IsoData,
258 }
259 }
260
261 pub fn from_hci_bytes_with_kind(
263 kind: PacketKind,
264 data: &'a [u8],
265 ) -> Result<(ControllerToHostPacket<'a>, &'a [u8]), FromHciBytesError> {
266 match kind {
267 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
268 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
269 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
270 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
271 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
272 }
273 }
274}
275
276impl<'de> FromHciBytes<'de> for ControllerToHostPacket<'de> {
277 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
278 let (kind, data) = PacketKind::from_hci_bytes(data)?;
279 match kind {
280 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
281 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
282 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
283 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
284 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
285 }
286 }
287}
288
289impl<'de> ReadHci<'de> for ControllerToHostPacket<'de> {
290 const MAX_LEN: usize = 258;
291
292 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
293 let mut kind = [0];
294 reader.read_exact(&mut kind)?;
295 match PacketKind::from_hci_bytes(&kind)?.0 {
296 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
297 PacketKind::AclData => data::AclPacket::read_hci(reader, buf).map(Self::Acl),
298 PacketKind::SyncData => data::SyncPacket::read_hci(reader, buf).map(Self::Sync),
299 PacketKind::Event => event::EventPacket::read_hci(reader, buf).map(Self::Event),
300 PacketKind::IsoData => data::IsoPacket::read_hci(reader, buf).map(Self::Iso),
301 }
302 }
303
304 async fn read_hci_async<R: embedded_io_async::Read>(
305 mut reader: R,
306 buf: &'de mut [u8],
307 ) -> Result<Self, ReadHciError<R::Error>> {
308 let mut kind = [0u8];
309 reader.read_exact(&mut kind).await?;
310 match PacketKind::from_hci_bytes(&kind)?.0 {
311 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
312 PacketKind::AclData => data::AclPacket::read_hci_async(reader, buf).await.map(Self::Acl),
313 PacketKind::SyncData => data::SyncPacket::read_hci_async(reader, buf).await.map(Self::Sync),
314 PacketKind::Event => event::EventPacket::read_hci_async(reader, buf).await.map(Self::Event),
315 PacketKind::IsoData => data::IsoPacket::read_hci_async(reader, buf).await.map(Self::Iso),
316 }
317 }
318}
319
320impl<'de> PacketToHost<'de> for ControllerToHostPacket<'de> {
321 fn read_hci<R: embedded_io::Read>(
322 kind: PacketKind,
323 reader: &mut R,
324 buf: &'de mut [u8],
325 ) -> Result<Self, ReadHciError<R::Error>> {
326 match kind {
327 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
328 PacketKind::AclData => data::AclPacket::read_hci(reader, buf).map(Self::Acl),
329 PacketKind::SyncData => data::SyncPacket::read_hci(reader, buf).map(Self::Sync),
330 PacketKind::Event => event::EventPacket::read_hci(reader, buf).map(Self::Event),
331 PacketKind::IsoData => data::IsoPacket::read_hci(reader, buf).map(Self::Iso),
332 }
333 }
334
335 async fn read_hci_async<R: embedded_io_async::Read>(
336 kind: PacketKind,
337 reader: &mut R,
338 buf: &'de mut [u8],
339 ) -> Result<Self, ReadHciError<R::Error>> {
340 match kind {
341 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
342 PacketKind::AclData => data::AclPacket::read_hci_async(reader, buf).await.map(Self::Acl),
343 PacketKind::SyncData => data::SyncPacket::read_hci_async(reader, buf).await.map(Self::Sync),
344 PacketKind::Event => event::EventPacket::read_hci_async(reader, buf).await.map(Self::Event),
345 PacketKind::IsoData => data::IsoPacket::read_hci_async(reader, buf).await.map(Self::Iso),
346 }
347 }
348}