1use crate::cmd::{Opcode, SyncCmd};
4use crate::param::{
5 param, AuthenticationRequirements, BdAddr, ClockOffset, ClockType, ConnHandle, ConnHandleCompletedPackets,
6 ConnectionLinkType, CoreSpecificationVersion, EncryptionEnabledLevel, Error, ExtendedLmpFeatures, FlowDirection,
7 IoCapability, KeyFlag, KeypressNotificationType, LinkKeyType, LinkType, LmpFeatureMask, MaxSlots, Mode,
8 OobDataPresent, PacketType, PageScanRepetitionMode, RemainingBytes, Role, ServiceType, Status,
9};
10use crate::{AsHciBytes, FromHciBytes, FromHciBytesError, ReadHci, ReadHciError};
11
12pub mod le;
13
14use le::LeEvent;
15
16pub trait EventParams<'a>: FromHciBytes<'a> {
18 const EVENT_CODE: u8;
20}
21
22param! {
23 struct EventPacketHeader {
25 code: u8,
26 params_len: u8,
27 }
28}
29
30macro_rules! events {
31 (
32 $(
33 $(#[$attrs:meta])*
34 struct $name:ident$(<$life:lifetime>)?($code:expr) {
35 $(
36 $(#[$field_attrs:meta])*
37 $field:ident: $ty:ty
38 ),*
39 $(,)?
40 }
41 )+
42 ) => {
43 #[non_exhaustive]
45 #[derive(Debug, Clone, Hash)]
46 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
47 pub enum Event<'a> {
48 $(
49 #[allow(missing_docs)]
50 $name($name$(<$life>)?),
51 )+
52 #[allow(missing_docs)]
53 Le(LeEvent<'a>),
54 Unknown {
56 code: u8,
58 params: &'a [u8]
60 },
61 }
62
63
64 #[non_exhaustive]
66 #[derive(Debug, Clone, Copy, Hash, PartialEq)]
67 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
68 pub struct EventKind(pub u8);
69
70 #[allow(non_upper_case_globals)]
71 impl EventKind {
72 $(
73 #[allow(missing_docs)]
74 pub const $name: EventKind = EventKind($code);
75 )+
76 #[allow(missing_docs)]
77 pub const Le: EventKind = EventKind(0x3e);
78 }
79
80 #[derive(Debug, Clone, Hash)]
82 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
83 pub struct EventPacket<'a> {
84 pub kind: EventKind,
86 pub data: &'a [u8],
88 }
89
90 impl<'a> EventPacket<'a> {
91 fn from_header_hci_bytes(header: EventPacketHeader, data: &'a [u8]) -> Result<Self, FromHciBytesError> {
92 let (kind, data) = EventKind::from_header_hci_bytes(header, data)?;
93 Ok(Self {
94 kind,
95 data,
96 })
97 }
98 }
99
100 impl EventKind {
101 fn from_header_hci_bytes(header: EventPacketHeader, data: &[u8]) -> Result<(Self, &[u8]), FromHciBytesError> {
102 let (data, _) = if data.len() < usize::from(header.params_len) {
103 return Err(FromHciBytesError::InvalidSize);
104 } else {
105 data.split_at(usize::from(header.params_len))
106 };
107
108 Ok((EventKind(header.code), data))
109 }
110 }
111
112 impl<'a> TryFrom<EventPacket<'a>> for Event<'a> {
113 type Error = FromHciBytesError;
114 fn try_from(packet: EventPacket<'a>) -> Result<Self, Self::Error> {
115 match packet.kind {
116 $(EventKind::$name => Ok(Self::$name($name::from_hci_bytes_complete(packet.data)?)),)+
117 EventKind::Le => {
118 Ok(Self::Le(LeEvent::from_hci_bytes_complete(packet.data)?))
119 }
120 EventKind(code) => Ok(Self::Unknown { code, params: packet.data }),
121 }
122 }
123 }
124
125 impl<'a> Event<'a> {
126 fn from_header_hci_bytes(header: EventPacketHeader, data: &'a [u8]) -> Result<(Self, &'a [u8]), FromHciBytesError> {
127 let (data, rest) = if data.len() < usize::from(header.params_len) {
128 return Err(FromHciBytesError::InvalidSize);
129 } else {
130 data.split_at(usize::from(header.params_len))
131 };
132
133 match header.code {
134 $($code => $name::from_hci_bytes_complete(data).map(|x| (Self::$name(x), rest)),)+
135 0x3e => LeEvent::from_hci_bytes_complete(data).map(|x| (Self::Le(x), rest)),
136 _ => {
137 Ok((Self::Unknown { code: header.code, params: data }, rest))
138 }
139 }
140 }
141 }
142
143 $(
144 $(#[$attrs])*
145 #[derive(Debug, Clone, Copy, Hash)]
146 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
147 pub struct $name$(<$life>)? {
148 $(
149 #[doc = stringify!($field)]
150 $(#[$field_attrs])*
151 pub $field: $ty,
152 )*
153 }
154
155 #[automatically_derived]
156 impl<'a> $crate::FromHciBytes<'a> for $name$(<$life>)? {
157 #[allow(unused_variables)]
158 fn from_hci_bytes(data: &'a [u8]) -> Result<(Self, &'a [u8]), $crate::FromHciBytesError> {
159 let total = 0;
160 $(
161 let ($field, data) = <$ty as $crate::FromHciBytes>::from_hci_bytes(data)?;
162 )*
163 Ok((Self {
164 $($field,)*
165 }, data))
166 }
167 }
168
169 #[automatically_derived]
170 impl<'a> $crate::event::EventParams<'a> for $name$(<$life>)? {
171 const EVENT_CODE: u8 = $code;
172 }
173 )+
174 };
175}
176
177events! {
178 struct InquiryComplete(0x01) {
182 status: Status,
183 }
184
185 struct InquiryResult<'a>(0x02) {
187 num_responses: u8,
188 bytes: RemainingBytes<'a>,
190 }
191
192 struct ConnectionComplete(0x03) {
194 status: Status,
195 handle: ConnHandle,
196 bd_addr: BdAddr,
197 link_type: ConnectionLinkType,
198 encryption_enabled: bool,
199 }
200
201 struct ConnectionRequest(0x04) {
203 bd_addr: BdAddr,
204 class_of_device: [u8; 3],
205 link_type: ConnectionLinkType,
206 }
207
208 struct DisconnectionComplete(0x05) {
210 status: Status,
211 handle: ConnHandle,
212 reason: Status,
213 }
214
215 struct AuthenticationComplete(0x06) {
217 status: Status,
218 handle: ConnHandle,
219 }
220
221 struct RemoteNameRequestComplete<'a>(0x07) {
223 status: Status,
224 bd_addr: BdAddr,
225 remote_name: RemainingBytes<'a>, }
227
228 struct EncryptionChangeV1(0x08) {
230 status: Status,
231 handle: ConnHandle,
232 enabled: EncryptionEnabledLevel,
233 }
234
235 struct ChangeConnectionLinkKeyComplete(0x09) {
237 status: Status,
238 handle: ConnHandle,
239 }
240
241 struct LinkKeyTypeChanged(0x0a) {
243 status: Status,
244 handle: ConnHandle,
245 key_flag: KeyFlag,
246 }
247
248 struct ReadRemoteSupportedFeaturesComplete(0x0b) {
250 status: Status,
251 handle: ConnHandle,
252 lmp_features: LmpFeatureMask,
253 }
254
255 struct ReadRemoteVersionInformationComplete(0x0c) {
257 status: Status,
258 handle: ConnHandle,
259 version: CoreSpecificationVersion,
260 company_id: u16,
261 subversion: u16,
262 }
263
264 struct QosSetupComplete(0x0d) {
266 status: Status,
267 handle: ConnHandle,
268 unused: u8, service_type: ServiceType,
270 token_rate: u32,
271 peak_bandwidth: u32,
272 latency: u32,
273 delay_variation: u32,
274 }
275
276 struct CommandComplete<'a>(0x0e) {
278 num_hci_cmd_pkts: u8,
279 cmd_opcode: Opcode,
280 bytes: RemainingBytes<'a>,
281 }
282
283 struct CommandStatus(0x0f) {
285 status: Status,
286 num_hci_cmd_pkts: u8,
287 cmd_opcode: Opcode,
288 }
289
290 struct HardwareError(0x10) {
294 hardware_code: u8,
295 }
296
297 struct FlushOccurred(0x11) {
299 handle: ConnHandle,
300 }
301
302 struct RoleChange(0x12) {
304 status: Status,
305 bd_addr: BdAddr,
306 new_role: Role,
307 }
308
309 struct NumberOfCompletedPackets<'a>(0x13) {
311 completed_packets: &'a [ConnHandleCompletedPackets],
312 }
313
314 struct ModeChange(0x14) {
316 status: Status,
317 handle: ConnHandle,
318 mode: Mode,
319 interval: u16,
320 }
321
322 struct ReturnLinkKeys<'a>(0x15) {
324 num_keys: u8,
325 bytes: RemainingBytes<'a>, }
327
328 struct PinCodeRequest(0x16) {
330 bd_addr: BdAddr,
331 }
332
333 struct LinkKeyRequest(0x17) {
335 bd_addr: BdAddr,
336 }
337
338 struct LinkKeyNotification(0x18) {
340 bd_addr: BdAddr,
341 link_key: [u8; 16],
342 key_type: LinkKeyType,
343 }
344
345 struct LoopbackCommand<'a>(0x19) {
347 command_packet: RemainingBytes<'a>,
348 }
349
350 struct DataBufferOverflow(0x1a) {
352 link_type: LinkType,
353 }
354
355 struct MaxSlotsChange(0x1b) {
357 handle: ConnHandle,
358 lmp_max_slots: MaxSlots,
359 }
360
361 struct ReadClockOffsetComplete(0x1c) {
363 status: Status,
364 handle: ConnHandle,
365 clock_offset: ClockOffset,
366 }
367
368 struct ConnectionPacketTypeChanged(0x1d) {
370 status: Status,
371 handle: ConnHandle,
372 packet_type: PacketType,
373 }
374
375 struct QosViolation(0x1e) {
377 handle: ConnHandle,
378 }
379
380 struct PageScanRepetitionModeChange(0x20) {
384 bd_addr: BdAddr,
385 page_scan_repetition_mode: PageScanRepetitionMode,
386 }
387
388 struct FlowSpecificationComplete(0x21) {
390 status: Status,
391 handle: ConnHandle,
392 unused: u8, flow_direction: FlowDirection,
394 service_type: ServiceType,
395 token_rate: u32,
396 token_bucket_size: u32,
397 peak_bandwidth: u32,
398 access_latency: u32,
399 }
400
401 struct InquiryResultWithRssi<'a>(0x22) {
403 num_responses: u8,
404 bytes: RemainingBytes<'a>,
406 }
407
408 struct ReadRemoteExtendedFeaturesComplete(0x23) {
410 status: Status,
411 handle: ConnHandle,
412 extended_lmp_features: ExtendedLmpFeatures,
413 }
414
415 struct SynchronousConnectionComplete(0x2c) {
417 status: Status,
418 handle: ConnHandle,
419 bd_addr: BdAddr,
420 link_type: ConnectionLinkType,
421 transmission_interval: u8,
422 retransmission_window: u8,
423 rx_packet_length: u16,
424 tx_packet_length: u16,
425 air_mode: u8,
426 }
427
428 struct SynchronousConnectionChanged(0x2d) {
430 status: Status,
431 handle: ConnHandle,
432 transmission_interval: u8,
433 retransmission_window: u8,
434 rx_packet_length: u16,
435 tx_packet_length: u16,
436 }
437
438
439 struct SniffSubrating(0x2e) {
441 status: Status,
442 handle: ConnHandle,
443 max_tx_latency: u16,
444 max_rx_latency: u16,
445 min_remote_timeout: u16,
446 min_local_timeout: u16,
447 }
448
449 struct ExtendedInquiryResult<'a>(0x2f) {
451 num_responses: u8,
452 bd_addr: BdAddr,
453 page_scan_repetition_mode: PageScanRepetitionMode,
454 reserved: u8,
455 class_of_device: [u8; 3],
456 clock_offset: ClockOffset,
457 rssi: i8,
458 eir_data: RemainingBytes<'a>,
459 }
460
461 struct EncryptionKeyRefreshComplete(0x30) {
465 status: Status,
466 handle: ConnHandle,
467 }
468
469 struct IoCapabilityRequest(0x31) {
471 bd_addr: BdAddr,
472 }
473
474 struct IoCapabilityResponse(0x32) {
476 bd_addr: BdAddr,
477 io_capability: IoCapability,
478 oob_data_present: OobDataPresent,
479 authentication_requirements: AuthenticationRequirements,
480 }
481
482 struct UserConfirmationRequest(0x33) {
484 bd_addr: BdAddr,
485 numeric_value: u32,
486 }
487
488 struct UserPasskeyRequest(0x34) {
490 bd_addr: BdAddr,
491 }
492
493 struct RemoteOobDataRequest(0x35) {
495 bd_addr: BdAddr,
496 }
497
498 struct SimplePairingComplete(0x36) {
500 status: Status,
501 bd_addr: BdAddr,
502 }
503
504 struct LinkSupervisionTimeoutChanged(0x38) {
506 handle: ConnHandle,
507 link_supervision_timeout: u16,
508 }
509
510 struct EnhancedFlushComplete(0x39) {
512 handle: ConnHandle,
513 }
514
515 struct UserPasskeyNotification(0x3b) {
517 bd_addr: BdAddr,
518 passkey: u32,
519 }
520
521 struct KeypressNotification(0x3c) {
523 bd_addr: BdAddr,
524 notification_type: KeypressNotificationType,
525 }
526
527 struct RemoteHostSupportedFeaturesNotification(0x3d) {
529 bd_addr: BdAddr,
530 features: LmpFeatureMask,
531 }
532
533 struct NumberOfCompletedDataBlocks<'a>(0x48) {
537 total_num_data_blocks: u16,
538 num_of_handles: u8,
539 bytes: RemainingBytes<'a>, }
541
542 struct TriggeredClockCapture(0x4e) {
544 handle: ConnHandle,
545 which_clock: ClockType,
546 clock: u32,
547 slot_offset: u16,
548 }
549
550 struct SynchronizationTrainComplete(0x4f) {
552 status: Status,
553 }
554
555 struct SynchronizationTrainReceived(0x50) {
559 status: Status,
560 bd_addr: BdAddr,
561 clock_offset: u32,
562 afh_channel_map: [u8; 10],
563 lt_addr: u8,
564 next_broadcast_instant: u32,
565 connectionless_peripheral_broadcast_interval: u16,
566 service_data: u8,
567 }
568
569 struct ConnectionlessPeripheralBroadcastReceive<'a>(0x51) {
571 bd_addr: BdAddr,
572 lt_addr: u8,
573 clock: u32,
574 offset: u32,
575 rx_status: u8,
576 fragment: u8,
577 data_length: u8,
578 data: RemainingBytes<'a>,
579 }
580
581 struct ConnectionlessPeripheralBroadcastTimeout(0x52) {
583 bd_addr: BdAddr,
584 lt_addr: u8,
585 }
586
587 struct TruncatedPageComplete(0x53) {
589 status: Status,
590 bd_addr: BdAddr,
591 }
592
593 struct PeripheralPageResponseTimeout(0x54) {
595 }
596
597 struct ConnectionlessPeripheralBroadcastChannelMapChange(0x55) {
599 channel_map: [u8; 10],
600 }
601
602 struct InquiryResponseNotification(0x56) {
604 lap: [u8; 3],
605 rssi: i8,
606 }
607
608 struct AuthenticatedPayloadTimeoutExpired(0x57) {
610 handle: ConnHandle,
611 }
612
613 struct SamStatusChange(0x58) {
615 handle: ConnHandle,
616 local_sam_index: u8,
617 local_sam_tx_availability: u8,
618 local_sam_rx_availability: u8,
619 remote_sam_index: u8,
620 remote_sam_tx_availability: u8,
621 remote_sam_rx_availability: u8,
622 }
623
624 struct EncryptionChangeV2(0x59) {
626 status: Status,
627 handle: ConnHandle,
628 encryption_enabled: EncryptionEnabledLevel,
629 encryption_key_size: u8,
630 }
631
632 struct Vendor<'a>(0xff) {
636 params: RemainingBytes<'a>,
637 }
638}
639
640impl<'de> FromHciBytes<'de> for Event<'de> {
641 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
642 let (header, data) = EventPacketHeader::from_hci_bytes(data)?;
643 Self::from_header_hci_bytes(header, data)
644 }
645}
646
647impl<'de> FromHciBytes<'de> for EventPacket<'de> {
648 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
649 let (header, data) = EventPacketHeader::from_hci_bytes(data)?;
650 let pkt = Self::from_header_hci_bytes(header, data)?;
651 Ok((pkt, &[]))
652 }
653}
654
655impl<'de> ReadHci<'de> for EventPacket<'de> {
656 const MAX_LEN: usize = 257;
657
658 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
659 let mut header = [0; 2];
660 reader.read_exact(&mut header)?;
661 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
662 let params_len = usize::from(header.params_len);
663 if buf.len() < params_len {
664 Err(ReadHciError::BufferTooSmall)
665 } else {
666 let (buf, _) = buf.split_at_mut(params_len);
667 reader.read_exact(buf)?;
668 let pkt = Self::from_header_hci_bytes(header, buf)?;
669 Ok(pkt)
670 }
671 }
672
673 async fn read_hci_async<R: embedded_io_async::Read>(
674 mut reader: R,
675 buf: &'de mut [u8],
676 ) -> Result<Self, ReadHciError<R::Error>> {
677 let mut header = [0; 2];
678 reader.read_exact(&mut header).await?;
679 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
680 let params_len = usize::from(header.params_len);
681 if buf.len() < params_len {
682 Err(ReadHciError::BufferTooSmall)
683 } else {
684 let (buf, _) = buf.split_at_mut(params_len);
685 reader.read_exact(buf).await?;
686 let pkt = Self::from_header_hci_bytes(header, buf)?;
687 Ok(pkt)
688 }
689 }
690}
691
692impl<'de> ReadHci<'de> for Event<'de> {
693 const MAX_LEN: usize = 257;
694
695 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
696 let mut header = [0; 2];
697 reader.read_exact(&mut header)?;
698 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
699 let params_len = usize::from(header.params_len);
700 if buf.len() < params_len {
701 Err(ReadHciError::BufferTooSmall)
702 } else {
703 let (buf, _) = buf.split_at_mut(params_len);
704 reader.read_exact(buf)?;
705 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
706 Ok(pkt)
707 }
708 }
709
710 async fn read_hci_async<R: embedded_io_async::Read>(
711 mut reader: R,
712 buf: &'de mut [u8],
713 ) -> Result<Self, ReadHciError<R::Error>> {
714 let mut header = [0; 2];
715 reader.read_exact(&mut header).await?;
716 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
717 let params_len = usize::from(header.params_len);
718 if buf.len() < params_len {
719 Err(ReadHciError::BufferTooSmall)
720 } else {
721 let (buf, _) = buf.split_at_mut(params_len);
722 reader.read_exact(buf).await?;
723 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
724 Ok(pkt)
725 }
726 }
727}
728
729impl CommandComplete<'_> {
730 pub fn has_status(&self) -> bool {
732 self.cmd_opcode != Opcode::UNSOLICITED
733 }
734}
735
736impl<'d> TryFrom<CommandComplete<'d>> for CommandCompleteWithStatus<'d> {
737 type Error = FromHciBytesError;
738 fn try_from(e: CommandComplete<'d>) -> Result<CommandCompleteWithStatus<'d>, Self::Error> {
739 if e.cmd_opcode == Opcode::UNSOLICITED {
740 return Err(FromHciBytesError::InvalidSize);
741 }
742 let bytes = e.bytes.into_inner();
743 let (status, remaining) = Status::from_hci_bytes(bytes)?;
744 let return_param_bytes: RemainingBytes<'d> = RemainingBytes::from_hci_bytes_complete(remaining)?;
745 Ok(Self {
746 num_hci_cmd_pkts: e.num_hci_cmd_pkts,
747 cmd_opcode: e.cmd_opcode,
748 status,
749 return_param_bytes,
750 })
751 }
752}
753
754#[derive(Debug, Clone, PartialEq, Eq)]
756pub struct CommandCompleteWithStatus<'d> {
757 pub num_hci_cmd_pkts: u8,
759 pub cmd_opcode: Opcode,
761 pub status: Status,
763 pub return_param_bytes: RemainingBytes<'d>,
765}
766
767impl CommandCompleteWithStatus<'_> {
768 pub fn handle<C: SyncCmd>(&self) -> Result<C::Handle, FromHciBytesError> {
773 C::return_handle(&self.return_param_bytes)
774 }
775
776 pub fn to_result<C: SyncCmd>(&self) -> Result<C::Return, Error> {
783 self.status
784 .to_result()
785 .and_then(|_| self.return_params::<C>().or(Err(Error::INVALID_HCI_PARAMETERS)))
786 }
787
788 pub fn return_params<C: SyncCmd>(&self) -> Result<C::Return, FromHciBytesError> {
795 assert_eq!(self.cmd_opcode, C::OPCODE);
796 C::Return::from_hci_bytes(&self.return_param_bytes).and_then(|(params, rest)| {
797 if rest.is_empty() {
798 Ok(params)
799 } else {
800 Err(FromHciBytesError::InvalidSize)
801 }
802 })
803 }
804}
805
806#[derive(Debug, Clone, PartialEq, Eq)]
808pub struct InquiryResultItem {
809 pub bd_addr: BdAddr,
811 pub page_scan_repetition_mode: Option<PageScanRepetitionMode>,
813 pub class_of_device: Option<[u8; 3]>,
815 pub clock_offset: Option<ClockOffset>,
817 pub rssi: Option<i8>,
820}
821
822pub struct InquiryResultIter<'a> {
824 bytes: &'a [u8],
825 num_responses: usize,
826 idx: usize,
827 kind: InquiryResultKind,
828}
829
830#[derive(Copy, Clone, Debug, PartialEq, Eq)]
832pub enum InquiryResultKind {
833 Standard,
835 WithRssi,
837}
838
839impl<'a> InquiryResultIter<'a> {
840 pub fn new_standard(bytes: &'a [u8], num_responses: usize) -> Self {
842 InquiryResultIter {
843 bytes,
844 num_responses,
845 idx: 0,
846 kind: InquiryResultKind::Standard,
847 }
848 }
849
850 pub fn new_with_rssi(bytes: &'a [u8], num_responses: usize) -> Self {
852 InquiryResultIter {
853 bytes,
854 num_responses,
855 idx: 0,
856 kind: InquiryResultKind::WithRssi,
857 }
858 }
859}
860
861impl Iterator for InquiryResultIter<'_> {
862 type Item = InquiryResultItem;
863 fn next(&mut self) -> Option<Self::Item> {
864 if self.idx >= self.num_responses {
865 return None;
866 }
867
868 let i = self.idx;
869 let n = self.num_responses;
870
871 let bd_addr_size = n * 6;
872 let page_scan_size = n;
873 let class_size = n * 3;
874 let clock_size = n * 2;
875
876 let reserved_size = match self.kind {
877 InquiryResultKind::Standard => n * 2,
878 InquiryResultKind::WithRssi => n,
879 };
880
881 let bd_addr_off = i * 6;
882 let page_scan_off = bd_addr_size + i;
883 let class_off = bd_addr_size + page_scan_size + reserved_size + i * 3;
884 let clock_off = bd_addr_size + page_scan_size + reserved_size + class_size + i * 2;
885
886 if self.bytes.len() < bd_addr_off + 6 {
887 return None;
888 }
889
890 let bd_addr = BdAddr::new([
891 self.bytes[bd_addr_off],
892 self.bytes[bd_addr_off + 1],
893 self.bytes[bd_addr_off + 2],
894 self.bytes[bd_addr_off + 3],
895 self.bytes[bd_addr_off + 4],
896 self.bytes[bd_addr_off + 5],
897 ]);
898
899 let page_scan_repetition_mode = self
900 .bytes
901 .get(page_scan_off)
902 .and_then(|b| PageScanRepetitionMode::from_hci_bytes(&[*b]).ok().map(|(m, _)| m));
903
904 let class_of_device = self.bytes.get(class_off..class_off + 3).map(|s| [s[0], s[1], s[2]]);
905
906 let clock_offset = self
907 .bytes
908 .get(clock_off..clock_off + 2)
909 .and_then(|s| ClockOffset::from_hci_bytes(s).ok().map(|(c, _)| c));
910
911 let rssi = if self.kind == InquiryResultKind::WithRssi {
912 let rssi_off = bd_addr_size + page_scan_size + reserved_size + class_size + clock_size + i;
913 self.bytes.get(rssi_off).map(|b| *b as i8)
914 } else {
915 None
916 };
917
918 self.idx += 1;
919
920 Some(InquiryResultItem {
921 bd_addr,
922 page_scan_repetition_mode,
923 class_of_device,
924 clock_offset,
925 rssi,
926 })
927 }
928}
929
930impl InquiryResult<'_> {
932 pub fn iter(&self) -> InquiryResultIter<'_> {
934 let bytes = self.bytes.as_hci_bytes();
935 let n = self.num_responses as usize;
936 InquiryResultIter::new_standard(bytes, n)
937 }
938}
939
940impl InquiryResultWithRssi<'_> {
942 pub fn iter(&self) -> InquiryResultIter<'_> {
944 let bytes = self.bytes.as_hci_bytes();
945 let n = self.num_responses as usize;
946 InquiryResultIter::new_with_rssi(bytes, n)
947 }
948}
949
950#[cfg(test)]
951mod tests {
952 use super::*;
953 use crate::cmd::OpcodeGroup;
954 use crate::event::le::LeEventPacket;
955 use crate::param::*;
956
957 #[test]
958 fn test_inquiry_result() {
959 let data = [
960 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x30, 0x05, 0x01, 0x34, 0x12, 0x78, 0x56, ];
968 let (inquiry_result, _) = InquiryResult::from_hci_bytes(&data).unwrap();
969
970 let mut iter = inquiry_result.iter();
971
972 let item1 = iter.next().unwrap();
973 assert_eq!(item1.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
974 assert_eq!(item1.page_scan_repetition_mode, Some(PageScanRepetitionMode::R1));
975 assert_eq!(item1.class_of_device, Some([0x20, 0x04, 0x00]));
976 assert_eq!(item1.clock_offset.unwrap().as_hci_bytes(), &[0x34, 0x12]);
977 assert_eq!(item1.rssi, None);
978
979 let item2 = iter.next().unwrap();
980 assert_eq!(item2.bd_addr.as_hci_bytes(), &[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
981 assert_eq!(item2.page_scan_repetition_mode, Some(PageScanRepetitionMode::R2));
982 assert_eq!(item2.class_of_device, Some([0x30, 0x05, 0x01]));
983 assert_eq!(item2.clock_offset.unwrap().as_hci_bytes(), &[0x78, 0x56]);
984 assert_eq!(item2.rssi, None);
985 assert!(iter.next().is_none());
986 }
987
988 #[test]
989 fn test_inquiry_result_with_rssi() {
990 let data = [
991 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x01, 0x02, 0x00, 0x00, 0x20, 0x04, 0x00, 0x30, 0x05, 0x01, 0x34, 0x12, 0x78, 0x56, 0xF0, 0xE8, ];
1000 let (inquiry_result, _) = InquiryResultWithRssi::from_hci_bytes(&data).unwrap();
1001
1002 let mut iter = inquiry_result.iter();
1003
1004 let item1 = iter.next().unwrap();
1005 assert_eq!(item1.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
1006 assert_eq!(item1.page_scan_repetition_mode, Some(PageScanRepetitionMode::R1));
1007 assert_eq!(item1.class_of_device, Some([0x20, 0x04, 0x00]));
1008 assert_eq!(item1.clock_offset.unwrap().as_hci_bytes(), &[0x34, 0x12]);
1009 assert_eq!(item1.rssi, Some(-16));
1010
1011 let item2 = iter.next().unwrap();
1012 assert_eq!(item2.bd_addr.as_hci_bytes(), &[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
1013 assert_eq!(item2.page_scan_repetition_mode, Some(PageScanRepetitionMode::R2));
1014 assert_eq!(item2.class_of_device, Some([0x30, 0x05, 0x01]));
1015 assert_eq!(item2.clock_offset.unwrap().as_hci_bytes(), &[0x78, 0x56]);
1016 assert_eq!(item2.rssi, Some(-24));
1017 assert!(iter.next().is_none());
1018 }
1019
1020 #[test]
1021 fn test_extended_inquiry_result() {
1022 let data = [
1023 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x00, 0x20, 0x04, 0x00, 0x34, 0x12, 0xF0, 0x09, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x76, ];
1032 let (eir_result, _) = ExtendedInquiryResult::from_hci_bytes(&data).unwrap();
1033
1034 assert_eq!(eir_result.num_responses, 1);
1035 assert_eq!(eir_result.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
1036 assert_eq!(eir_result.page_scan_repetition_mode, PageScanRepetitionMode::R1);
1037 assert_eq!(eir_result.reserved, 0x00);
1038 assert_eq!(eir_result.class_of_device, [0x20, 0x04, 0x00]);
1039 assert_eq!(eir_result.clock_offset.as_hci_bytes(), &[0x34, 0x12]);
1040 assert_eq!(eir_result.rssi, -16);
1041 assert_eq!(
1042 eir_result.eir_data.as_hci_bytes(),
1043 &[0x09, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x76]
1044 );
1045 }
1046
1047 #[test]
1048 fn test_io_capability_request() {
1049 let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
1050 let (evt, rest) = IoCapabilityRequest::from_hci_bytes(&data).unwrap();
1051 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1052 assert!(rest.is_empty());
1053 }
1054
1055 #[test]
1056 fn test_user_confirmation_request() {
1057 let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x78, 0x56, 0x34, 0x12];
1058 let (evt, rest) = UserConfirmationRequest::from_hci_bytes(&data).unwrap();
1059 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1060 assert_eq!(evt.numeric_value, 0x1234_5678);
1061 assert!(rest.is_empty());
1062 }
1063
1064 #[test]
1065 fn test_connection_request() {
1066 let data = [
1067 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x20, 0x04, 0x00, 0x01, ];
1071 let (evt, rest) = ConnectionRequest::from_hci_bytes(&data).unwrap();
1072 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1073 assert_eq!(evt.class_of_device, [0x20, 0x04, 0x00]);
1074 assert_eq!(evt.link_type, ConnectionLinkType::Acl);
1075 assert!(rest.is_empty());
1076 }
1077
1078 #[test]
1079 fn test_role_change() {
1080 let data = [
1081 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, ];
1085 let (evt, rest) = RoleChange::from_hci_bytes(&data).unwrap();
1086 assert_eq!(evt.status, Status::SUCCESS);
1087 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1088 assert_eq!(evt.new_role, Role::Central);
1089 assert!(rest.is_empty());
1090 }
1091
1092 #[test]
1093 fn test_simple_pairing_complete() {
1094 let data = [
1095 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, ];
1098 let (evt, rest) = SimplePairingComplete::from_hci_bytes(&data).unwrap();
1099 assert_eq!(evt.status, Status::SUCCESS);
1100 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1101 assert!(rest.is_empty());
1102 }
1103
1104 #[test]
1105 fn test_io_capability_response() {
1106 let data = [
1107 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x00, 0x03, ];
1112 let (evt, rest) = IoCapabilityResponse::from_hci_bytes(&data).unwrap();
1113 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1114 assert_eq!(evt.io_capability, IoCapability::DisplayYesNo);
1115 assert_eq!(evt.oob_data_present, OobDataPresent::NotPresent);
1116 assert_eq!(
1117 evt.authentication_requirements,
1118 AuthenticationRequirements::MitmRequiredDedicatedBonding
1119 );
1120 assert!(rest.is_empty());
1121 }
1122
1123 #[test]
1124 fn test_number_of_completed_data_blocks() {
1125 let data = [
1126 0x00, 0x10, 0x02, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, ];
1135 let (evt, rest) = NumberOfCompletedDataBlocks::from_hci_bytes(&data).unwrap();
1136 assert_eq!(evt.total_num_data_blocks, 4096);
1137 assert_eq!(evt.num_of_handles, 2);
1138 assert_eq!(evt.bytes.as_hci_bytes().len(), 12); assert!(rest.is_empty());
1140 }
1141
1142 #[test]
1143 fn test_connectionless_peripheral_broadcast_receive() {
1144 let data = [
1145 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x00, 0x01, 0x04, 0xAA, 0xBB, 0xCC, 0xDD, ];
1154 let (evt, rest) = ConnectionlessPeripheralBroadcastReceive::from_hci_bytes(&data).unwrap();
1155 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1156 assert_eq!(evt.lt_addr, 0x07);
1157 assert_eq!(evt.clock, 0x78563412);
1158 assert_eq!(evt.offset, 0xF0DEBC9A);
1159 assert_eq!(evt.rx_status, 0x00);
1160 assert_eq!(evt.fragment, 0x01);
1161 assert_eq!(evt.data_length, 0x04);
1162 assert_eq!(evt.data.as_hci_bytes(), &[0xAA, 0xBB, 0xCC, 0xDD]);
1163 assert!(rest.is_empty());
1164 }
1165
1166 #[test]
1167 fn test_connectionless_peripheral_broadcast_timeout() {
1168 let data = [
1169 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ];
1172 let (evt, rest) = ConnectionlessPeripheralBroadcastTimeout::from_hci_bytes(&data).unwrap();
1173 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1174 assert_eq!(evt.lt_addr, 0x07);
1175 assert!(rest.is_empty());
1176 }
1177
1178 #[test]
1179 fn test_truncated_page_complete() {
1180 let data = [
1181 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, ];
1184 let (evt, rest) = TruncatedPageComplete::from_hci_bytes(&data).unwrap();
1185 assert_eq!(evt.status, Status::SUCCESS);
1186 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1187 assert!(rest.is_empty());
1188 }
1189
1190 #[test]
1191 fn test_peripheral_page_response_timeout() {
1192 let data = [];
1193 let (_evt, rest) = PeripheralPageResponseTimeout::from_hci_bytes(&data).unwrap();
1194 assert!(rest.is_empty());
1195 }
1196
1197 #[test]
1198 fn test_connectionless_peripheral_broadcast_channel_map_change() {
1199 let data = [
1200 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, ];
1202 let (evt, rest) = ConnectionlessPeripheralBroadcastChannelMapChange::from_hci_bytes(&data).unwrap();
1203 assert_eq!(
1204 evt.channel_map,
1205 [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A]
1206 );
1207 assert!(rest.is_empty());
1208 }
1209
1210 #[test]
1211 fn test_sam_status_change() {
1212 let data = [
1213 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ];
1221 let (evt, rest) = SamStatusChange::from_hci_bytes(&data).unwrap();
1222 assert_eq!(evt.handle.raw(), 1);
1223 assert_eq!(evt.local_sam_index, 0x02);
1224 assert_eq!(evt.local_sam_tx_availability, 0x03);
1225 assert_eq!(evt.local_sam_rx_availability, 0x04);
1226 assert_eq!(evt.remote_sam_index, 0x05);
1227 assert_eq!(evt.remote_sam_tx_availability, 0x06);
1228 assert_eq!(evt.remote_sam_rx_availability, 0x07);
1229 assert!(rest.is_empty());
1230 }
1231
1232 #[test]
1233 fn convert_error_packet() {
1234 let data = [
1235 0x04, 10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x20, 0x04, 0x00, 0x01, ];
1239 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1240 assert!(matches!(event.kind, EventKind::ConnectionRequest));
1241
1242 let Event::ConnectionRequest(evt) = Event::try_from(event).unwrap() else {
1243 unreachable!()
1244 };
1245
1246 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1247 assert_eq!(evt.class_of_device, [0x20, 0x04, 0x00]);
1248 assert_eq!(evt.link_type, ConnectionLinkType::Acl);
1249 }
1250
1251 #[test]
1252 fn convert_le_error_packet() {
1253 let data = [
1254 0x3e, 19, 1, 0, 1, 0, 0, 1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 1, ];
1266 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1267 assert!(matches!(event.kind, EventKind::Le));
1268
1269 let Event::Le(LeEvent::LeConnectionComplete(e)) = Event::try_from(event).unwrap() else {
1270 unreachable!()
1271 };
1272
1273 assert_eq!(e.status, Status::SUCCESS);
1274 assert_eq!(e.handle, ConnHandle::new(1));
1275 assert!(matches!(e.central_clock_accuracy, ClockAccuracy::Ppm250));
1276 }
1277
1278 #[test]
1279 fn parse_le_packet() {
1280 let data = [
1281 0x3e, 19, 1, 0, 1, 0, 0, 1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 1, ];
1293 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1294 assert!(matches!(event.kind, EventKind::Le));
1295 let event = LeEventPacket::from_hci_bytes_complete(event.data).unwrap();
1296 assert!(matches!(
1297 event.kind,
1298 crate::event::le::LeEventKind::LeConnectionComplete
1299 ));
1300 let e = crate::event::le::LeConnectionComplete::from_hci_bytes_complete(event.data).unwrap();
1301
1302 assert_eq!(e.status, Status::SUCCESS);
1303 assert_eq!(e.handle, ConnHandle::new(1));
1304 assert!(matches!(e.central_clock_accuracy, ClockAccuracy::Ppm250));
1305 }
1306
1307 #[test]
1308 fn test_special_command_complete() {
1309 let data = [
1310 0x0e, 3, 1, 0, 0, ];
1313
1314 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1315 assert!(matches!(event.kind, EventKind::CommandComplete));
1316 let event = CommandComplete::from_hci_bytes_complete(event.data).unwrap();
1317 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::new(0), 0));
1318 }
1319
1320 #[test]
1321 fn test_normal_command_complete() {
1322 let opcode = Opcode::new(OpcodeGroup::LE, 0x000D).to_raw().to_le_bytes();
1323 let data = [
1324 0x0e, 4, 1, opcode[0], opcode[1], 0, ];
1328
1329 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1330 assert!(matches!(event.kind, EventKind::CommandComplete));
1331 let event = CommandComplete::from_hci_bytes_complete(event.data).unwrap();
1332 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::LE, 0x000d));
1333
1334 let event: CommandCompleteWithStatus = event.try_into().unwrap();
1335 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::LE, 0x000d));
1336 assert_eq!(Status::SUCCESS, event.status);
1337 }
1338}