1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![no_std]
4
5use core::future::Future;
6
7use embedded_io::ReadExactError;
8
9mod fmt;
10
11pub mod cmd;
12pub mod controller;
13pub mod data;
14pub mod event;
15pub mod param;
16pub mod transport;
17pub use btuuid as uuid;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21#[cfg_attr(feature = "defmt", derive(defmt::Format))]
22pub enum FromHciBytesError {
23 InvalidSize,
25 InvalidValue,
27}
28
29pub trait AsHciBytes {
31 fn as_hci_bytes(&self) -> &[u8];
33}
34
35pub trait FromHciBytes<'de>: Sized {
37 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError>;
39
40 fn from_hci_bytes_complete(data: &'de [u8]) -> Result<Self, FromHciBytesError> {
42 let (val, buf) = Self::from_hci_bytes(data)?;
43 if buf.is_empty() {
44 Ok(val)
45 } else {
46 Err(FromHciBytesError::InvalidSize)
47 }
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53#[cfg_attr(feature = "defmt", derive(defmt::Format))]
54pub enum ReadHciError<E: embedded_io::Error> {
55 BufferTooSmall,
57 InvalidValue,
59 Read(ReadExactError<E>),
61}
62
63impl<E: embedded_io::Error> embedded_io::Error for ReadHciError<E> {
64 fn kind(&self) -> embedded_io::ErrorKind {
65 match self {
66 Self::BufferTooSmall => embedded_io::ErrorKind::OutOfMemory,
67 Self::InvalidValue => embedded_io::ErrorKind::InvalidInput,
68 Self::Read(ReadExactError::Other(e)) => e.kind(),
69 Self::Read(ReadExactError::UnexpectedEof) => embedded_io::ErrorKind::BrokenPipe,
70 }
71 }
72}
73
74impl<E: embedded_io::Error> From<ReadExactError<E>> for ReadHciError<E> {
75 fn from(value: ReadExactError<E>) -> Self {
76 ReadHciError::Read(value)
77 }
78}
79
80impl<E: embedded_io::Error> From<FromHciBytesError> for ReadHciError<E> {
81 fn from(value: FromHciBytesError) -> Self {
82 match value {
83 FromHciBytesError::InvalidSize => ReadHciError::Read(ReadExactError::UnexpectedEof),
84 FromHciBytesError::InvalidValue => ReadHciError::InvalidValue,
85 }
86 }
87}
88
89pub trait ReadHci<'de>: FromHciBytes<'de> {
91 const MAX_LEN: usize;
93
94 fn read_hci<R: embedded_io::Read>(reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>>;
96
97 fn read_hci_async<R: embedded_io_async::Read>(
99 reader: R,
100 buf: &'de mut [u8],
101 ) -> impl Future<Output = Result<Self, ReadHciError<R::Error>>>;
102}
103
104pub trait WriteHci {
106 fn size(&self) -> usize;
108
109 fn write_hci<W: embedded_io::Write>(&self, writer: W) -> Result<(), W::Error>;
111
112 fn write_hci_async<W: embedded_io_async::Write>(&self, writer: W) -> impl Future<Output = Result<(), W::Error>>;
114}
115
116pub trait HostToControllerPacket: WriteHci {
118 const KIND: PacketKind;
120}
121
122pub unsafe trait FixedSizeValue: Copy {
131 fn is_valid(data: &[u8]) -> bool;
135}
136
137pub unsafe trait ByteAlignedValue: FixedSizeValue {
142 fn ref_from_hci_bytes(data: &[u8]) -> Result<(&Self, &[u8]), FromHciBytesError> {
147 if data.len() < core::mem::size_of::<Self>() {
148 Err(FromHciBytesError::InvalidSize)
149 } else if !Self::is_valid(data) {
150 Err(FromHciBytesError::InvalidValue)
151 } else {
152 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
153 Ok((unsafe { &*(data.as_ptr() as *const Self) }, rest))
154 }
155 }
156}
157
158impl<T: FixedSizeValue> AsHciBytes for T {
159 fn as_hci_bytes(&self) -> &[u8] {
160 unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, core::mem::size_of::<Self>()) }
161 }
162}
163
164impl<'de, T: FixedSizeValue> FromHciBytes<'de> for T {
165 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
166 if data.len() < core::mem::size_of::<Self>() {
167 Err(FromHciBytesError::InvalidSize)
168 } else if !Self::is_valid(data) {
169 Err(FromHciBytesError::InvalidValue)
170 } else {
171 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
172 Ok((unsafe { core::ptr::read_unaligned(data.as_ptr() as *const Self) }, rest))
173 }
174 }
175}
176
177impl<'de, T: ByteAlignedValue> FromHciBytes<'de> for &'de [T] {
178 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
179 let Some((len, data)) = data.split_first() else {
180 return Err(FromHciBytesError::InvalidSize);
181 };
182
183 let len = usize::from(*len);
184 let byte_len = len * core::mem::size_of::<T>();
185 if byte_len > data.len() {
186 return Err(FromHciBytesError::InvalidSize);
187 }
188
189 let (data, rest) = data.split_at(byte_len);
190
191 if !data.chunks_exact(core::mem::size_of::<T>()).all(|x| T::is_valid(x)) {
192 return Err(FromHciBytesError::InvalidValue);
193 }
194
195 Ok((
196 unsafe { core::slice::from_raw_parts(data.as_ptr() as *const T, len) },
197 rest,
198 ))
199 }
200}
201
202impl<'de, T: FixedSizeValue> ReadHci<'de> for T {
203 const MAX_LEN: usize = core::mem::size_of::<Self>();
204
205 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
206 if buf.len() < core::mem::size_of::<Self>() {
207 Err(ReadHciError::BufferTooSmall)
208 } else {
209 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
210 reader.read_exact(buf)?;
211 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
212 }
213 }
214
215 async fn read_hci_async<R: embedded_io_async::Read>(
216 mut reader: R,
217 buf: &'de mut [u8],
218 ) -> Result<Self, ReadHciError<R::Error>> {
219 if buf.len() < core::mem::size_of::<Self>() {
220 Err(ReadHciError::BufferTooSmall)
221 } else {
222 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
223 reader.read_exact(buf).await?;
224 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
225 }
226 }
227}
228
229impl<T: FixedSizeValue> WriteHci for T {
230 #[inline(always)]
231 fn size(&self) -> usize {
232 core::mem::size_of::<Self>()
233 }
234
235 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
236 writer.write_all(self.as_hci_bytes())
237 }
238
239 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
240 writer.write_all(self.as_hci_bytes()).await
241 }
242}
243
244#[repr(u8)]
246#[derive(Debug, Clone, Copy, PartialEq, Eq)]
247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
248pub enum PacketKind {
249 Cmd = 1,
251 AclData = 2,
253 SyncData = 3,
255 Event = 4,
257 IsoData = 5,
259}
260
261impl<'de> FromHciBytes<'de> for PacketKind {
262 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
263 if data.is_empty() {
264 Err(FromHciBytesError::InvalidSize)
265 } else {
266 let (data, rest) = data.split_at(1);
267 match data[0] {
268 1 => Ok((PacketKind::Cmd, rest)),
269 2 => Ok((PacketKind::AclData, rest)),
270 3 => Ok((PacketKind::SyncData, rest)),
271 4 => Ok((PacketKind::Event, rest)),
272 5 => Ok((PacketKind::IsoData, rest)),
273 _ => Err(FromHciBytesError::InvalidValue),
274 }
275 }
276 }
277}
278
279impl WriteHci for PacketKind {
280 #[inline(always)]
281 fn size(&self) -> usize {
282 1
283 }
284
285 #[inline(always)]
286 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
287 writer.write_all(&(*self as u8).to_le_bytes())
288 }
289
290 #[inline(always)]
291 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
292 writer.write_all(&(*self as u8).to_le_bytes()).await
293 }
294}
295
296#[derive(Debug)]
298#[cfg_attr(feature = "defmt", derive(defmt::Format))]
299pub enum ControllerToHostPacket<'a> {
300 Acl(data::AclPacket<'a>),
302 Sync(data::SyncPacket<'a>),
304 Event(event::EventPacket<'a>),
306 Iso(data::IsoPacket<'a>),
308}
309
310impl<'a> ControllerToHostPacket<'a> {
311 pub fn kind(&self) -> PacketKind {
313 match self {
314 Self::Acl(_) => PacketKind::AclData,
315 Self::Sync(_) => PacketKind::SyncData,
316 Self::Event(_) => PacketKind::Event,
317 Self::Iso(_) => PacketKind::IsoData,
318 }
319 }
320
321 pub fn from_hci_bytes_with_kind(
323 kind: PacketKind,
324 data: &'a [u8],
325 ) -> Result<(ControllerToHostPacket<'a>, &'a [u8]), FromHciBytesError> {
326 match kind {
327 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
328 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
329 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
330 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
331 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
332 }
333 }
334}
335
336impl<'de> FromHciBytes<'de> for ControllerToHostPacket<'de> {
337 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
338 let (kind, data) = PacketKind::from_hci_bytes(data)?;
339 match kind {
340 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
341 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
342 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
343 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
344 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
345 }
346 }
347}
348
349impl<'de> ReadHci<'de> for ControllerToHostPacket<'de> {
350 const MAX_LEN: usize = 258;
351
352 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
353 let mut kind = [0];
354 reader.read_exact(&mut kind)?;
355 match PacketKind::from_hci_bytes(&kind)?.0 {
356 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
357 PacketKind::AclData => data::AclPacket::read_hci(reader, buf).map(Self::Acl),
358 PacketKind::SyncData => data::SyncPacket::read_hci(reader, buf).map(Self::Sync),
359 PacketKind::Event => event::EventPacket::read_hci(reader, buf).map(Self::Event),
360 PacketKind::IsoData => data::IsoPacket::read_hci(reader, buf).map(Self::Iso),
361 }
362 }
363
364 async fn read_hci_async<R: embedded_io_async::Read>(
365 mut reader: R,
366 buf: &'de mut [u8],
367 ) -> Result<Self, ReadHciError<R::Error>> {
368 let mut kind = [0u8];
369 reader.read_exact(&mut kind).await?;
370 match PacketKind::from_hci_bytes(&kind)?.0 {
371 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
372 PacketKind::AclData => data::AclPacket::read_hci_async(reader, buf).await.map(Self::Acl),
373 PacketKind::SyncData => data::SyncPacket::read_hci_async(reader, buf).await.map(Self::Sync),
374 PacketKind::Event => event::EventPacket::read_hci_async(reader, buf).await.map(Self::Event),
375 PacketKind::IsoData => data::IsoPacket::read_hci_async(reader, buf).await.map(Self::Iso),
376 }
377 }
378}