1use crate::param::{param, ConnHandle};
4use crate::{FromHciBytes, FromHciBytesError, HostToControllerPacket, PacketKind, ReadHci, ReadHciError, WriteHci};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9#[repr(u8)]
10pub enum AclPacketBoundary {
11 FirstNonFlushable = 0x00,
14 Continuing = 0x01,
16 FirstFlushable = 0x02,
18 Complete = 0x03,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25#[repr(u8)]
26pub enum AclBroadcastFlag {
27 PointToPoint = 0x00,
29 BrEdrBroadcast = 0x01,
31 Reserved = 0x02,
33}
34
35param! {
36 struct AclPacketHeader {
38 handle: u16,
39 data_len: u16,
40 }
41}
42
43impl AclPacketHeader {
44 pub fn handle(&self) -> ConnHandle {
46 ConnHandle::new(self.handle & 0xfff)
47 }
48
49 pub fn boundary_flag(&self) -> AclPacketBoundary {
51 match (self.handle >> 12) & 0x03 {
52 0 => AclPacketBoundary::FirstNonFlushable,
53 1 => AclPacketBoundary::Continuing,
54 2 => AclPacketBoundary::FirstFlushable,
55 3 => AclPacketBoundary::Complete,
56 _ => unreachable!(),
57 }
58 }
59
60 pub fn broadcast_flag(&self) -> AclBroadcastFlag {
62 match (self.handle >> 14) & 0x03 {
63 0 => AclBroadcastFlag::PointToPoint,
64 1 => AclBroadcastFlag::BrEdrBroadcast,
65 2 => AclBroadcastFlag::Reserved,
66 3 => AclBroadcastFlag::Reserved,
67 _ => unreachable!(),
68 }
69 }
70
71 pub fn data_len(&self) -> usize {
73 usize::from(self.data_len)
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
79#[cfg_attr(feature = "defmt", derive(defmt::Format))]
80pub struct AclPacket<'a> {
81 handle: u16,
82 data: &'a [u8],
83}
84
85impl<'a> AclPacket<'a> {
86 pub fn new(handle: ConnHandle, pbf: AclPacketBoundary, bf: AclBroadcastFlag, data: &'a [u8]) -> Self {
88 let handle: u16 = handle.into_inner() | ((pbf as u16) << 12) | ((bf as u16) << 14);
89 Self { handle, data }
90 }
91
92 pub fn from_header_hci_bytes(
94 header: AclPacketHeader,
95 data: &'a [u8],
96 ) -> Result<(Self, &'a [u8]), FromHciBytesError> {
97 let data_len = usize::from(header.data_len);
98 if data.len() < data_len {
99 Err(FromHciBytesError::InvalidSize)
100 } else {
101 let (data, rest) = data.split_at(data_len);
102 Ok((
103 Self {
104 handle: header.handle,
105 data: &data[..data_len],
106 },
107 rest,
108 ))
109 }
110 }
111
112 pub fn handle(&self) -> ConnHandle {
114 ConnHandle::new(self.handle & 0xfff)
115 }
116
117 pub fn header(&self) -> AclPacketHeader {
119 AclPacketHeader {
120 handle: self.handle,
121 data_len: self.data.len() as u16,
122 }
123 }
124
125 pub fn boundary_flag(&self) -> AclPacketBoundary {
127 match (self.handle >> 12) & 0x03 {
128 0 => AclPacketBoundary::FirstNonFlushable,
129 1 => AclPacketBoundary::Continuing,
130 2 => AclPacketBoundary::FirstFlushable,
131 3 => AclPacketBoundary::Complete,
132 _ => unreachable!(),
133 }
134 }
135
136 pub fn broadcast_flag(&self) -> AclBroadcastFlag {
138 match (self.handle >> 14) & 0x03 {
139 0 => AclBroadcastFlag::PointToPoint,
140 1 => AclBroadcastFlag::BrEdrBroadcast,
141 2 => AclBroadcastFlag::Reserved,
142 3 => AclBroadcastFlag::Reserved,
143 _ => unreachable!(),
144 }
145 }
146
147 pub fn data(&self) -> &'a [u8] {
149 self.data
150 }
151}
152
153impl<'de> FromHciBytes<'de> for AclPacket<'de> {
154 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
155 let (header, data) = AclPacketHeader::from_hci_bytes(data)?;
156 Self::from_header_hci_bytes(header, data)
157 }
158}
159
160impl<'de> ReadHci<'de> for AclPacket<'de> {
161 const MAX_LEN: usize = 255;
162
163 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
164 let mut header = [0; 4];
165 reader.read_exact(&mut header)?;
166 let (header, _) = AclPacketHeader::from_hci_bytes(&header)?;
167 let data_len = header.data_len();
168 if buf.len() < data_len {
169 Err(ReadHciError::BufferTooSmall)
170 } else {
171 let (buf, _) = buf.split_at_mut(data_len);
172 reader.read_exact(buf)?;
173 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
174 Ok(pkt)
175 }
176 }
177
178 async fn read_hci_async<R: embedded_io_async::Read>(
179 mut reader: R,
180 buf: &'de mut [u8],
181 ) -> Result<Self, ReadHciError<R::Error>> {
182 let mut header = [0; 4];
183 reader.read_exact(&mut header).await?;
184 let (header, _) = AclPacketHeader::from_hci_bytes(&header)?;
185 let data_len = header.data_len();
186 if buf.len() < data_len {
187 Err(ReadHciError::BufferTooSmall)
188 } else {
189 let (buf, _) = buf.split_at_mut(data_len);
190 reader.read_exact(buf).await?;
191 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
192 Ok(pkt)
193 }
194 }
195}
196
197impl WriteHci for AclPacket<'_> {
198 #[inline(always)]
199 fn size(&self) -> usize {
200 4 + self.data.len()
201 }
202
203 #[inline(always)]
204 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
205 let header = AclPacketHeader {
206 handle: self.handle,
207 data_len: self.data.len() as u16,
208 };
209 header.write_hci(&mut writer)?;
210 writer.write_all(self.data)
211 }
212
213 #[inline(always)]
214 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
215 let header = AclPacketHeader {
216 handle: self.handle,
217 data_len: self.data.len() as u16,
218 };
219 header.write_hci_async(&mut writer).await?;
220 writer.write_all(self.data).await
221 }
222}
223
224impl HostToControllerPacket for AclPacket<'_> {
225 const KIND: PacketKind = PacketKind::AclData;
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
231pub enum SyncPacketStatus {
232 Correct,
235 PossiblyInvalid,
239 NoData,
243 PartiallyLost,
247}
248
249param! {
250 struct SyncPacketHeader {
252 handle: u16,
253 data_len: u8,
254 }
255}
256
257impl SyncPacketHeader {
258 pub fn handle(&self) -> ConnHandle {
260 ConnHandle::new(self.handle & 0xfff)
261 }
262
263 pub fn status(&self) -> SyncPacketStatus {
265 match (self.handle >> 12) & 0x03 {
266 0 => SyncPacketStatus::Correct,
267 1 => SyncPacketStatus::PossiblyInvalid,
268 2 => SyncPacketStatus::NoData,
269 3 => SyncPacketStatus::PartiallyLost,
270 _ => unreachable!(),
271 }
272 }
273
274 pub fn data_len(&self) -> usize {
276 usize::from(self.data_len)
277 }
278}
279
280#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
282#[cfg_attr(feature = "defmt", derive(defmt::Format))]
283pub struct SyncPacket<'a> {
284 handle: u16,
285 data: &'a [u8],
286}
287
288impl<'a> SyncPacket<'a> {
289 pub fn from_header_hci_bytes(
291 header: SyncPacketHeader,
292 data: &'a [u8],
293 ) -> Result<(Self, &'a [u8]), FromHciBytesError> {
294 let data_len = usize::from(header.data_len);
295 if data.len() < data_len {
296 Err(FromHciBytesError::InvalidSize)
297 } else {
298 let (data, rest) = data.split_at(data_len);
299 Ok((
300 Self {
301 handle: header.handle,
302 data: &data[..data_len],
303 },
304 rest,
305 ))
306 }
307 }
308
309 pub fn handle(&self) -> ConnHandle {
311 ConnHandle::new(self.handle & 0xfff)
312 }
313
314 pub fn status(&self) -> SyncPacketStatus {
316 match (self.handle >> 12) & 0x03 {
317 0 => SyncPacketStatus::Correct,
318 1 => SyncPacketStatus::PossiblyInvalid,
319 2 => SyncPacketStatus::NoData,
320 3 => SyncPacketStatus::PartiallyLost,
321 _ => unreachable!(),
322 }
323 }
324
325 pub fn data(&self) -> &[u8] {
327 self.data
328 }
329}
330
331impl<'de> FromHciBytes<'de> for SyncPacket<'de> {
332 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
333 let (header, data) = SyncPacketHeader::from_hci_bytes(data)?;
334 Self::from_header_hci_bytes(header, data)
335 }
336}
337
338impl<'de> ReadHci<'de> for SyncPacket<'de> {
339 const MAX_LEN: usize = 258;
340
341 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
342 let mut header = [0; 3];
343 reader.read_exact(&mut header)?;
344 let (header, _) = SyncPacketHeader::from_hci_bytes(&header)?;
345 let data_len = header.data_len();
346 if buf.len() < data_len {
347 Err(ReadHciError::BufferTooSmall)
348 } else {
349 let (buf, _) = buf.split_at_mut(data_len);
350 reader.read_exact(buf)?;
351 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
352 Ok(pkt)
353 }
354 }
355
356 async fn read_hci_async<R: embedded_io_async::Read>(
357 mut reader: R,
358 buf: &'de mut [u8],
359 ) -> Result<Self, ReadHciError<R::Error>> {
360 let mut header = [0; 3];
361 reader.read_exact(&mut header).await?;
362 let (header, _) = SyncPacketHeader::from_hci_bytes(&header)?;
363 let data_len = header.data_len();
364 if buf.len() < data_len {
365 Err(ReadHciError::BufferTooSmall)
366 } else {
367 let (buf, _) = buf.split_at_mut(data_len);
368 reader.read_exact(buf).await?;
369 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
370 Ok(pkt)
371 }
372 }
373}
374
375impl WriteHci for SyncPacket<'_> {
376 #[inline(always)]
377 fn size(&self) -> usize {
378 4 + self.data.len()
379 }
380
381 #[inline(always)]
382 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
383 let header = SyncPacketHeader {
384 handle: self.handle,
385 data_len: self.data.len() as u8,
386 };
387 header.write_hci(&mut writer)?;
388 writer.write_all(self.data)
389 }
390
391 #[inline(always)]
392 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
393 let header = SyncPacketHeader {
394 handle: self.handle,
395 data_len: self.data.len() as u8,
396 };
397 header.write_hci_async(&mut writer).await?;
398 writer.write_all(self.data).await
399 }
400}
401
402impl HostToControllerPacket for SyncPacket<'_> {
403 const KIND: PacketKind = PacketKind::SyncData;
404}
405
406#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
408#[cfg_attr(feature = "defmt", derive(defmt::Format))]
409pub enum IsoPacketBoundary {
410 FirstFragment,
412 ContinuationFragment,
414 Complete,
416 LastFragment,
418}
419
420#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
422#[cfg_attr(feature = "defmt", derive(defmt::Format))]
423pub enum IsoPacketStatus {
424 Correct,
426 PossiblyInvalid,
429 PartiallyLost,
431}
432
433param! {
434 struct IsoPacketHeader {
436 handle: u16,
437 data_load_len: u16,
438 }
439}
440
441impl IsoPacketHeader {
442 pub fn handle(&self) -> ConnHandle {
444 ConnHandle::new(self.handle & 0xfff)
445 }
446
447 pub fn boundary_flag(&self) -> IsoPacketBoundary {
449 match (self.handle >> 12) & 0x03 {
450 0 => IsoPacketBoundary::FirstFragment,
451 1 => IsoPacketBoundary::ContinuationFragment,
452 2 => IsoPacketBoundary::Complete,
453 3 => IsoPacketBoundary::LastFragment,
454 _ => unreachable!(),
455 }
456 }
457
458 pub fn has_timestamp(&self) -> bool {
460 ((self.handle >> 14) & 1) != 0
461 }
462
463 pub fn data_load_len(&self) -> usize {
469 usize::from(self.data_load_len)
470 }
471}
472
473#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
475#[cfg_attr(feature = "defmt", derive(defmt::Format))]
476pub struct IsoDataLoadHeader {
477 pub timestamp: Option<u32>,
481 pub sequence_num: u16,
485 pub iso_sdu_len: u16,
487}
488
489impl IsoDataLoadHeader {
490 pub fn from_hci_bytes(timestamp: bool, data: &[u8]) -> Result<(Self, &[u8]), FromHciBytesError> {
494 let (timestamp, data) = if timestamp {
495 u32::from_hci_bytes(data).map(|(x, y)| (Some(x), y))?
496 } else {
497 (None, data)
498 };
499
500 let (sequence_num, data) = u16::from_hci_bytes(data)?;
501 let (iso_sdu_len, data) = u16::from_hci_bytes(data)?;
502
503 Ok((
504 Self {
505 timestamp,
506 sequence_num,
507 iso_sdu_len,
508 },
509 data,
510 ))
511 }
512}
513
514impl WriteHci for IsoDataLoadHeader {
515 #[inline(always)]
516 fn size(&self) -> usize {
517 if self.timestamp.is_some() {
518 8
519 } else {
520 4
521 }
522 }
523
524 #[inline(always)]
525 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
526 if let Some(timestamp) = self.timestamp {
527 timestamp.write_hci(&mut writer)?;
528 }
529 self.sequence_num.write_hci(&mut writer)?;
530 self.iso_sdu_len.write_hci(writer)
531 }
532
533 #[inline(always)]
534 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
535 if let Some(timestamp) = self.timestamp {
536 timestamp.write_hci_async(&mut writer).await?;
537 }
538 self.sequence_num.write_hci_async(&mut writer).await?;
539 self.iso_sdu_len.write_hci_async(writer).await
540 }
541}
542
543#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
545#[cfg_attr(feature = "defmt", derive(defmt::Format))]
546pub struct IsoPacket<'a> {
547 handle: u16,
548 data_load_header: Option<IsoDataLoadHeader>,
549 data: &'a [u8],
550}
551
552impl<'a> IsoPacket<'a> {
553 pub fn from_header_hci_bytes(
555 header: IsoPacketHeader,
556 data: &'a [u8],
557 ) -> Result<(Self, &'a [u8]), FromHciBytesError> {
558 let data_load_len = usize::from(header.data_load_len);
559 if data.len() < data_load_len {
560 Err(FromHciBytesError::InvalidSize)
561 } else {
562 let (data, rest) = data.split_at(data_load_len);
563 let (data_load_header, data) = match header.boundary_flag() {
564 IsoPacketBoundary::FirstFragment | IsoPacketBoundary::Complete => {
565 IsoDataLoadHeader::from_hci_bytes(header.has_timestamp(), &data[..data_load_len])
566 .map(|(x, y)| (Some(x), y))?
567 }
568 IsoPacketBoundary::ContinuationFragment | IsoPacketBoundary::LastFragment => (None, data),
569 };
570
571 Ok((
572 Self {
573 handle: header.handle,
574 data_load_header,
575 data,
576 },
577 rest,
578 ))
579 }
580 }
581
582 pub fn handle(&self) -> ConnHandle {
584 ConnHandle::new(self.handle & 0xfff)
585 }
586
587 pub fn boundary_flag(&self) -> IsoPacketBoundary {
589 match (self.handle >> 12) & 0x03 {
590 0 => IsoPacketBoundary::FirstFragment,
591 1 => IsoPacketBoundary::ContinuationFragment,
592 2 => IsoPacketBoundary::Complete,
593 3 => IsoPacketBoundary::LastFragment,
594 _ => unreachable!(),
595 }
596 }
597
598 pub fn data_load_header(&self) -> Option<IsoDataLoadHeader> {
600 self.data_load_header
601 }
602
603 pub fn data_load_len(&self) -> usize {
605 self.data_load_header.as_ref().map(|x| x.size()).unwrap_or_default() + self.data.len()
606 }
607
608 pub fn data(&self) -> &[u8] {
610 self.data
611 }
612}
613
614impl<'de> FromHciBytes<'de> for IsoPacket<'de> {
615 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
616 let (header, data) = IsoPacketHeader::from_hci_bytes(data)?;
617 Self::from_header_hci_bytes(header, data)
618 }
619}
620
621impl<'de> ReadHci<'de> for IsoPacket<'de> {
622 const MAX_LEN: usize = 255;
623
624 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
625 let mut header = [0; 4];
626 reader.read_exact(&mut header)?;
627 let (header, _) = IsoPacketHeader::from_hci_bytes(&header)?;
628 let data_load_len = header.data_load_len();
629 if buf.len() < data_load_len {
630 Err(ReadHciError::BufferTooSmall)
631 } else {
632 let (buf, _) = buf.split_at_mut(data_load_len);
633 reader.read_exact(buf)?;
634 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
635 Ok(pkt)
636 }
637 }
638
639 async fn read_hci_async<R: embedded_io_async::Read>(
640 mut reader: R,
641 buf: &'de mut [u8],
642 ) -> Result<Self, ReadHciError<R::Error>> {
643 let mut header = [0; 4];
644 reader.read_exact(&mut header).await?;
645 let (header, _) = IsoPacketHeader::from_hci_bytes(&header)?;
646 let data_load_len = header.data_load_len();
647 if buf.len() < data_load_len {
648 Err(ReadHciError::BufferTooSmall)
649 } else {
650 let (buf, _) = buf.split_at_mut(data_load_len);
651 reader.read_exact(buf).await?;
652 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
653 Ok(pkt)
654 }
655 }
656}
657
658impl WriteHci for IsoPacket<'_> {
659 #[inline(always)]
660 fn size(&self) -> usize {
661 4 + self.data_load_len()
662 }
663
664 #[inline(always)]
665 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
666 let header = IsoPacketHeader {
667 handle: self.handle,
668 data_load_len: self.data_load_len() as u16,
669 };
670 header.write_hci(&mut writer)?;
671 if let Some(data_load_header) = &self.data_load_header {
672 data_load_header.write_hci(&mut writer)?;
673 }
674 writer.write_all(self.data)
675 }
676
677 #[inline(always)]
678 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
679 let header = IsoPacketHeader {
680 handle: self.handle,
681 data_load_len: self.data_load_len() as u16,
682 };
683 header.write_hci_async(&mut writer).await?;
684 if let Some(data_load_header) = &self.data_load_header {
685 data_load_header.write_hci_async(&mut writer).await?;
686 }
687 writer.write_all(self.data).await
688 }
689}
690
691impl HostToControllerPacket for IsoPacket<'_> {
692 const KIND: PacketKind = PacketKind::IsoData;
693}
694
695#[cfg(test)]
696mod tests {
697 use super::AclPacketHeader;
698 use crate::param::ConnHandle;
699 use crate::FromHciBytes;
700
701 #[test]
702 fn test_decode_acl_handle() {
703 let input = &[32, 32, 0, 0];
704 let header = AclPacketHeader::from_hci_bytes_complete(input).unwrap();
705 assert_eq!(header.handle(), ConnHandle::new(32));
706
707 let input = &[0, 33, 0, 0];
708 let header = AclPacketHeader::from_hci_bytes_complete(input).unwrap();
709 assert_eq!(header.handle(), ConnHandle::new(256));
710 }
711}