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> core::fmt::Display for ReadHciError<E> {
64 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65 write!(f, "{:?}", self)
66 }
67}
68
69impl<E: embedded_io::Error> core::error::Error for ReadHciError<E> {}
70
71impl<E: embedded_io::Error> embedded_io::Error for ReadHciError<E> {
72 fn kind(&self) -> embedded_io::ErrorKind {
73 match self {
74 Self::BufferTooSmall => embedded_io::ErrorKind::OutOfMemory,
75 Self::InvalidValue => embedded_io::ErrorKind::InvalidInput,
76 Self::Read(ReadExactError::Other(e)) => e.kind(),
77 Self::Read(ReadExactError::UnexpectedEof) => embedded_io::ErrorKind::BrokenPipe,
78 }
79 }
80}
81
82impl<E: embedded_io::Error> From<ReadExactError<E>> for ReadHciError<E> {
83 fn from(value: ReadExactError<E>) -> Self {
84 ReadHciError::Read(value)
85 }
86}
87
88impl<E: embedded_io::Error> From<FromHciBytesError> for ReadHciError<E> {
89 fn from(value: FromHciBytesError) -> Self {
90 match value {
91 FromHciBytesError::InvalidSize => ReadHciError::Read(ReadExactError::UnexpectedEof),
92 FromHciBytesError::InvalidValue => ReadHciError::InvalidValue,
93 }
94 }
95}
96
97pub trait ReadHci<'de>: FromHciBytes<'de> {
99 const MAX_LEN: usize;
101
102 fn read_hci<R: embedded_io::Read>(reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>>;
104
105 fn read_hci_async<R: embedded_io_async::Read>(
107 reader: R,
108 buf: &'de mut [u8],
109 ) -> impl Future<Output = Result<Self, ReadHciError<R::Error>>>;
110}
111
112pub trait WriteHci {
114 fn size(&self) -> usize;
116
117 fn write_hci<W: embedded_io::Write>(&self, writer: W) -> Result<(), W::Error>;
119
120 fn write_hci_async<W: embedded_io_async::Write>(&self, writer: W) -> impl Future<Output = Result<(), W::Error>>;
122}
123
124pub trait HostToControllerPacket: WriteHci {
126 const KIND: PacketKind;
128}
129
130pub unsafe trait FixedSizeValue: Copy {
139 fn is_valid(data: &[u8]) -> bool;
143}
144
145pub unsafe trait ByteAlignedValue: FixedSizeValue {
150 fn ref_from_hci_bytes(data: &[u8]) -> Result<(&Self, &[u8]), FromHciBytesError> {
155 if data.len() < core::mem::size_of::<Self>() {
156 Err(FromHciBytesError::InvalidSize)
157 } else if !Self::is_valid(data) {
158 Err(FromHciBytesError::InvalidValue)
159 } else {
160 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
161 Ok((unsafe { &*(data.as_ptr() as *const Self) }, rest))
162 }
163 }
164}
165
166impl<T: FixedSizeValue> AsHciBytes for T {
167 fn as_hci_bytes(&self) -> &[u8] {
168 unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, core::mem::size_of::<Self>()) }
169 }
170}
171
172impl<'de, T: FixedSizeValue> FromHciBytes<'de> for T {
173 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
174 if data.len() < core::mem::size_of::<Self>() {
175 Err(FromHciBytesError::InvalidSize)
176 } else if !Self::is_valid(data) {
177 Err(FromHciBytesError::InvalidValue)
178 } else {
179 let (data, rest) = data.split_at(core::mem::size_of::<Self>());
180 Ok((unsafe { core::ptr::read_unaligned(data.as_ptr() as *const Self) }, rest))
181 }
182 }
183}
184
185impl<'de, T: ByteAlignedValue> FromHciBytes<'de> for &'de [T] {
186 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
187 let Some((len, data)) = data.split_first() else {
188 return Err(FromHciBytesError::InvalidSize);
189 };
190
191 let len = usize::from(*len);
192 let byte_len = len * core::mem::size_of::<T>();
193 if byte_len > data.len() {
194 return Err(FromHciBytesError::InvalidSize);
195 }
196
197 let (data, rest) = data.split_at(byte_len);
198
199 if !data.chunks_exact(core::mem::size_of::<T>()).all(|x| T::is_valid(x)) {
200 return Err(FromHciBytesError::InvalidValue);
201 }
202
203 Ok((
204 unsafe { core::slice::from_raw_parts(data.as_ptr() as *const T, len) },
205 rest,
206 ))
207 }
208}
209
210impl<'de, T: FixedSizeValue> ReadHci<'de> for T {
211 const MAX_LEN: usize = core::mem::size_of::<Self>();
212
213 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
214 if buf.len() < core::mem::size_of::<Self>() {
215 Err(ReadHciError::BufferTooSmall)
216 } else {
217 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
218 reader.read_exact(buf)?;
219 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
220 }
221 }
222
223 async fn read_hci_async<R: embedded_io_async::Read>(
224 mut reader: R,
225 buf: &'de mut [u8],
226 ) -> Result<Self, ReadHciError<R::Error>> {
227 if buf.len() < core::mem::size_of::<Self>() {
228 Err(ReadHciError::BufferTooSmall)
229 } else {
230 let (buf, _) = buf.split_at_mut(core::mem::size_of::<Self>());
231 reader.read_exact(buf).await?;
232 Self::from_hci_bytes(buf).map(|(x, _)| x).map_err(Into::into)
233 }
234 }
235}
236
237impl<T: FixedSizeValue> WriteHci for T {
238 #[inline(always)]
239 fn size(&self) -> usize {
240 core::mem::size_of::<Self>()
241 }
242
243 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
244 writer.write_all(self.as_hci_bytes())
245 }
246
247 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
248 writer.write_all(self.as_hci_bytes()).await
249 }
250}
251
252#[repr(u8)]
254#[derive(Debug, Clone, Copy, PartialEq, Eq)]
255#[cfg_attr(feature = "defmt", derive(defmt::Format))]
256pub enum PacketKind {
257 Cmd = 1,
259 AclData = 2,
261 SyncData = 3,
263 Event = 4,
265 IsoData = 5,
267}
268
269impl<'de> FromHciBytes<'de> for PacketKind {
270 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
271 if data.is_empty() {
272 Err(FromHciBytesError::InvalidSize)
273 } else {
274 let (data, rest) = data.split_at(1);
275 match data[0] {
276 1 => Ok((PacketKind::Cmd, rest)),
277 2 => Ok((PacketKind::AclData, rest)),
278 3 => Ok((PacketKind::SyncData, rest)),
279 4 => Ok((PacketKind::Event, rest)),
280 5 => Ok((PacketKind::IsoData, rest)),
281 _ => Err(FromHciBytesError::InvalidValue),
282 }
283 }
284 }
285}
286
287impl WriteHci for PacketKind {
288 #[inline(always)]
289 fn size(&self) -> usize {
290 1
291 }
292
293 #[inline(always)]
294 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
295 writer.write_all(&(*self as u8).to_le_bytes())
296 }
297
298 #[inline(always)]
299 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
300 writer.write_all(&(*self as u8).to_le_bytes()).await
301 }
302}
303
304#[derive(Debug)]
306#[cfg_attr(feature = "defmt", derive(defmt::Format))]
307pub enum ControllerToHostPacket<'a> {
308 Acl(data::AclPacket<'a>),
310 Sync(data::SyncPacket<'a>),
312 Event(event::EventPacket<'a>),
314 Iso(data::IsoPacket<'a>),
316}
317
318impl<'a> ControllerToHostPacket<'a> {
319 pub fn kind(&self) -> PacketKind {
321 match self {
322 Self::Acl(_) => PacketKind::AclData,
323 Self::Sync(_) => PacketKind::SyncData,
324 Self::Event(_) => PacketKind::Event,
325 Self::Iso(_) => PacketKind::IsoData,
326 }
327 }
328
329 pub fn from_hci_bytes_with_kind(
331 kind: PacketKind,
332 data: &'a [u8],
333 ) -> Result<(ControllerToHostPacket<'a>, &'a [u8]), FromHciBytesError> {
334 match kind {
335 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
336 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
337 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
338 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
339 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
340 }
341 }
342}
343
344impl<'de> FromHciBytes<'de> for ControllerToHostPacket<'de> {
345 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
346 let (kind, data) = PacketKind::from_hci_bytes(data)?;
347 match kind {
348 PacketKind::Cmd => Err(FromHciBytesError::InvalidValue),
349 PacketKind::AclData => data::AclPacket::from_hci_bytes(data).map(|(x, y)| (Self::Acl(x), y)),
350 PacketKind::SyncData => data::SyncPacket::from_hci_bytes(data).map(|(x, y)| (Self::Sync(x), y)),
351 PacketKind::Event => event::EventPacket::from_hci_bytes(data).map(|(x, y)| (Self::Event(x), y)),
352 PacketKind::IsoData => data::IsoPacket::from_hci_bytes(data).map(|(x, y)| (Self::Iso(x), y)),
353 }
354 }
355}
356
357impl<'de> ReadHci<'de> for ControllerToHostPacket<'de> {
358 const MAX_LEN: usize = 258;
359
360 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
361 let mut kind = [0];
362 reader.read_exact(&mut kind)?;
363 match PacketKind::from_hci_bytes(&kind)?.0 {
364 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
365 PacketKind::AclData => data::AclPacket::read_hci(reader, buf).map(Self::Acl),
366 PacketKind::SyncData => data::SyncPacket::read_hci(reader, buf).map(Self::Sync),
367 PacketKind::Event => event::EventPacket::read_hci(reader, buf).map(Self::Event),
368 PacketKind::IsoData => data::IsoPacket::read_hci(reader, buf).map(Self::Iso),
369 }
370 }
371
372 async fn read_hci_async<R: embedded_io_async::Read>(
373 mut reader: R,
374 buf: &'de mut [u8],
375 ) -> Result<Self, ReadHciError<R::Error>> {
376 let mut kind = [0u8];
377 reader.read_exact(&mut kind).await?;
378 match PacketKind::from_hci_bytes(&kind)?.0 {
379 PacketKind::Cmd => Err(ReadHciError::InvalidValue),
380 PacketKind::AclData => data::AclPacket::read_hci_async(reader, buf).await.map(Self::Acl),
381 PacketKind::SyncData => data::SyncPacket::read_hci_async(reader, buf).await.map(Self::Sync),
382 PacketKind::Event => event::EventPacket::read_hci_async(reader, buf).await.map(Self::Event),
383 PacketKind::IsoData => data::IsoPacket::read_hci_async(reader, buf).await.map(Self::Iso),
384 }
385 }
386}