1use crate::cmd::{Opcode, SyncCmd};
4use crate::param::{
5 param, AuthenticationRequirements, BdAddr, ClockOffset, ClockType, ConnHandle, ConnHandleCompletedPackets,
6 ConnectionLinkType, CoreSpecificationVersion, EncryptionEnabledLevel, Error, FlowDirection, IoCapability, KeyFlag,
7 KeypressNotificationType, LinkKeyType, LinkType, LmpFeatureMask, MaxSlots, Mode, OobDataPresent, PacketType,
8 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(0x3F);
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 match header.code {
109 $($code => Ok((Self::$name, data)),)+
110 0x3e => Ok((Self::Le, data)),
111 _ => {
112 Ok((EventKind(header.code), data))
113 }
114 }
115 }
116 }
117
118 impl<'a> TryFrom<EventPacket<'a>> for Event<'a> {
119 type Error = FromHciBytesError;
120 fn try_from(packet: EventPacket<'a>) -> Result<Self, Self::Error> {
121 match packet.kind {
122 $(EventKind::$name => Ok(Self::$name($name::from_hci_bytes_complete(packet.data)?)),)+
123 EventKind::Le => {
124 Ok(Self::Le(LeEvent::from_hci_bytes_complete(packet.data)?))
125 }
126 EventKind(code) => Ok(Self::Unknown { code, params: packet.data }),
127 }
128 }
129 }
130
131 impl<'a> Event<'a> {
132 fn from_header_hci_bytes(header: EventPacketHeader, data: &'a [u8]) -> Result<(Self, &'a [u8]), FromHciBytesError> {
133 let (data, rest) = if data.len() < usize::from(header.params_len) {
134 return Err(FromHciBytesError::InvalidSize);
135 } else {
136 data.split_at(usize::from(header.params_len))
137 };
138
139 match header.code {
140 $($code => $name::from_hci_bytes_complete(data).map(|x| (Self::$name(x), rest)),)+
141 0x3e => LeEvent::from_hci_bytes_complete(data).map(|x| (Self::Le(x), rest)),
142 _ => {
143 Ok((Self::Unknown { code: header.code, params: data }, rest))
144 }
145 }
146 }
147 }
148
149 $(
150 $(#[$attrs])*
151 #[derive(Debug, Clone, Copy, Hash)]
152 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
153 pub struct $name$(<$life>)? {
154 $(
155 #[doc = stringify!($field)]
156 $(#[$field_attrs])*
157 pub $field: $ty,
158 )*
159 }
160
161 #[automatically_derived]
162 impl<'a> $crate::FromHciBytes<'a> for $name$(<$life>)? {
163 #[allow(unused_variables)]
164 fn from_hci_bytes(data: &'a [u8]) -> Result<(Self, &'a [u8]), $crate::FromHciBytesError> {
165 let total = 0;
166 $(
167 let ($field, data) = <$ty as $crate::FromHciBytes>::from_hci_bytes(data)?;
168 )*
169 Ok((Self {
170 $($field,)*
171 }, data))
172 }
173 }
174
175 #[automatically_derived]
176 impl<'a> $crate::event::EventParams<'a> for $name$(<$life>)? {
177 const EVENT_CODE: u8 = $code;
178 }
179 )+
180 };
181}
182
183events! {
184 struct InquiryComplete(0x01) {
188 status: Status,
189 }
190
191 struct InquiryResult<'a>(0x02) {
193 num_responses: u8,
194 bytes: RemainingBytes<'a>,
196 }
197
198 struct ConnectionComplete(0x03) {
200 status: Status,
201 handle: ConnHandle,
202 bd_addr: BdAddr,
203 link_type: ConnectionLinkType,
204 encryption_enabled: bool,
205 }
206
207 struct ConnectionRequest(0x04) {
209 bd_addr: BdAddr,
210 class_of_device: [u8; 3],
211 link_type: ConnectionLinkType,
212 }
213
214 struct DisconnectionComplete(0x05) {
216 status: Status,
217 handle: ConnHandle,
218 reason: Status,
219 }
220
221 struct AuthenticationComplete(0x06) {
223 status: Status,
224 handle: ConnHandle,
225 }
226
227 struct RemoteNameRequestComplete<'a>(0x07) {
229 status: Status,
230 bd_addr: BdAddr,
231 remote_name: RemainingBytes<'a>, }
233
234 struct EncryptionChangeV1(0x08) {
236 status: Status,
237 handle: ConnHandle,
238 enabled: EncryptionEnabledLevel,
239 }
240
241 struct ChangeConnectionLinkKeyComplete(0x09) {
243 status: Status,
244 handle: ConnHandle,
245 }
246
247 struct LinkKeyTypeChanged(0x0a) {
249 status: Status,
250 handle: ConnHandle,
251 key_flag: KeyFlag,
252 }
253
254 struct ReadRemoteSupportedFeaturesComplete(0x0b) {
256 status: Status,
257 handle: ConnHandle,
258 lmp_features: LmpFeatureMask,
259 }
260
261 struct ReadRemoteVersionInformationComplete(0x0c) {
263 status: Status,
264 handle: ConnHandle,
265 version: CoreSpecificationVersion,
266 company_id: u16,
267 subversion: u16,
268 }
269
270 struct QosSetupComplete(0x0d) {
272 status: Status,
273 handle: ConnHandle,
274 unused: u8, service_type: ServiceType,
276 token_rate: u32,
277 peak_bandwidth: u32,
278 latency: u32,
279 delay_variation: u32,
280 }
281
282 struct CommandComplete<'a>(0x0e) {
284 num_hci_cmd_pkts: u8,
285 cmd_opcode: Opcode,
286 bytes: RemainingBytes<'a>,
287 }
288
289 struct CommandStatus(0x0f) {
291 status: Status,
292 num_hci_cmd_pkts: u8,
293 cmd_opcode: Opcode,
294 }
295
296 struct HardwareError(0x10) {
300 hardware_code: u8,
301 }
302
303 struct FlushOccurred(0x11) {
305 handle: ConnHandle,
306 }
307
308 struct RoleChange(0x12) {
310 status: Status,
311 bd_addr: BdAddr,
312 new_role: Role,
313 }
314
315 struct NumberOfCompletedPackets<'a>(0x13) {
317 completed_packets: &'a [ConnHandleCompletedPackets],
318 }
319
320 struct ModeChange(0x14) {
322 status: Status,
323 handle: ConnHandle,
324 mode: Mode,
325 interval: u16,
326 }
327
328 struct ReturnLinkKeys<'a>(0x15) {
330 num_keys: u8,
331 bytes: RemainingBytes<'a>, }
333
334 struct PinCodeRequest(0x16) {
336 bd_addr: BdAddr,
337 }
338
339 struct LinkKeyRequest(0x17) {
341 bd_addr: BdAddr,
342 }
343
344 struct LinkKeyNotification(0x18) {
346 bd_addr: BdAddr,
347 link_key: [u8; 16],
348 key_type: LinkKeyType,
349 }
350
351 struct LoopbackCommand<'a>(0x19) {
353 command_packet: RemainingBytes<'a>,
354 }
355
356 struct DataBufferOverflow(0x1a) {
358 link_type: LinkType,
359 }
360
361 struct MaxSlotsChange(0x1b) {
363 handle: ConnHandle,
364 lmp_max_slots: MaxSlots,
365 }
366
367 struct ReadClockOffsetComplete(0x1c) {
369 status: Status,
370 handle: ConnHandle,
371 clock_offset: ClockOffset,
372 }
373
374 struct ConnectionPacketTypeChanged(0x1d) {
376 status: Status,
377 handle: ConnHandle,
378 packet_type: PacketType,
379 }
380
381 struct QosViolation(0x1e) {
383 handle: ConnHandle,
384 }
385
386 struct PageScanRepetitionModeChange(0x20) {
390 bd_addr: BdAddr,
391 page_scan_repetition_mode: PageScanRepetitionMode,
392 }
393
394 struct FlowSpecificationComplete(0x21) {
396 status: Status,
397 handle: ConnHandle,
398 unused: u8, flow_direction: FlowDirection,
400 service_type: ServiceType,
401 token_rate: u32,
402 token_bucket_size: u32,
403 peak_bandwidth: u32,
404 access_latency: u32,
405 }
406
407 struct InquiryResultWithRssi<'a>(0x22) {
409 num_responses: u8,
410 bytes: RemainingBytes<'a>,
412 }
413
414 struct ReadRemoteExtendedFeaturesComplete(0x23) {
416 status: Status,
417 handle: ConnHandle,
418 page_number: u8,
419 maximum_page_number: u8,
420 extended_lmp_features: LmpFeatureMask,
421 }
422
423 struct SynchronousConnectionComplete(0x2c) {
425 status: Status,
426 handle: ConnHandle,
427 bd_addr: BdAddr,
428 link_type: ConnectionLinkType,
429 transmission_interval: u8,
430 retransmission_window: u8,
431 rx_packet_length: u16,
432 tx_packet_length: u16,
433 air_mode: u8,
434 }
435
436 struct SynchronousConnectionChanged(0x2d) {
438 status: Status,
439 handle: ConnHandle,
440 transmission_interval: u8,
441 retransmission_window: u8,
442 rx_packet_length: u16,
443 tx_packet_length: u16,
444 }
445
446
447 struct SniffSubrating(0x2e) {
449 status: Status,
450 handle: ConnHandle,
451 max_tx_latency: u16,
452 max_rx_latency: u16,
453 min_remote_timeout: u16,
454 min_local_timeout: u16,
455 }
456
457 struct ExtendedInquiryResult<'a>(0x2f) {
459 num_responses: u8,
460 bd_addr: BdAddr,
461 page_scan_repetition_mode: PageScanRepetitionMode,
462 reserved: u8,
463 class_of_device: [u8; 3],
464 clock_offset: ClockOffset,
465 rssi: i8,
466 eir_data: RemainingBytes<'a>,
467 }
468
469 struct EncryptionKeyRefreshComplete(0x30) {
473 status: Status,
474 handle: ConnHandle,
475 }
476
477 struct IoCapabilityRequest(0x31) {
479 bd_addr: BdAddr,
480 }
481
482 struct IoCapabilityResponse(0x32) {
484 bd_addr: BdAddr,
485 io_capability: IoCapability,
486 oob_data_present: OobDataPresent,
487 authentication_requirements: AuthenticationRequirements,
488 }
489
490 struct UserConfirmationRequest(0x33) {
492 bd_addr: BdAddr,
493 numeric_value: u32,
494 }
495
496 struct UserPasskeyRequest(0x34) {
498 bd_addr: BdAddr,
499 }
500
501 struct RemoteOobDataRequest(0x35) {
503 bd_addr: BdAddr,
504 }
505
506 struct SimplePairingComplete(0x36) {
508 status: Status,
509 bd_addr: BdAddr,
510 }
511
512 struct LinkSupervisionTimeoutChanged(0x38) {
514 handle: ConnHandle,
515 link_supervision_timeout: u16,
516 }
517
518 struct EnhancedFlushComplete(0x39) {
520 handle: ConnHandle,
521 }
522
523 struct UserPasskeyNotification(0x3b) {
525 bd_addr: BdAddr,
526 passkey: u32,
527 }
528
529 struct KeypressNotification(0x3c) {
531 bd_addr: BdAddr,
532 notification_type: KeypressNotificationType,
533 }
534
535 struct RemoteHostSupportedFeaturesNotification(0x3d) {
537 bd_addr: BdAddr,
538 features: LmpFeatureMask,
539 }
540
541 struct NumberOfCompletedDataBlocks<'a>(0x48) {
545 total_num_data_blocks: u16,
546 num_of_handles: u8,
547 bytes: RemainingBytes<'a>, }
549
550 struct TriggeredClockCapture(0x4e) {
552 handle: ConnHandle,
553 which_clock: ClockType,
554 clock: u32,
555 slot_offset: u16,
556 }
557
558 struct SynchronizationTrainComplete(0x4f) {
560 status: Status,
561 }
562
563 struct SynchronizationTrainReceived(0x50) {
567 status: Status,
568 bd_addr: BdAddr,
569 clock_offset: u32,
570 afh_channel_map: [u8; 10],
571 lt_addr: u8,
572 next_broadcast_instant: u32,
573 connectionless_peripheral_broadcast_interval: u16,
574 service_data: u8,
575 }
576
577 struct ConnectionlessPeripheralBroadcastReceive<'a>(0x51) {
579 bd_addr: BdAddr,
580 lt_addr: u8,
581 clock: u32,
582 offset: u32,
583 rx_status: u8,
584 fragment: u8,
585 data_length: u8,
586 data: RemainingBytes<'a>,
587 }
588
589 struct ConnectionlessPeripheralBroadcastTimeout(0x52) {
591 bd_addr: BdAddr,
592 lt_addr: u8,
593 }
594
595 struct TruncatedPageComplete(0x53) {
597 status: Status,
598 bd_addr: BdAddr,
599 }
600
601 struct PeripheralPageResponseTimeout(0x54) {
603 }
604
605 struct ConnectionlessPeripheralBroadcastChannelMapChange(0x55) {
607 channel_map: [u8; 10],
608 }
609
610 struct InquiryResponseNotification(0x56) {
612 lap: [u8; 3],
613 rssi: i8,
614 }
615
616 struct AuthenticatedPayloadTimeoutExpired(0x57) {
618 handle: ConnHandle,
619 }
620
621 struct SamStatusChange(0x58) {
623 handle: ConnHandle,
624 local_sam_index: u8,
625 local_sam_tx_availability: u8,
626 local_sam_rx_availability: u8,
627 remote_sam_index: u8,
628 remote_sam_tx_availability: u8,
629 remote_sam_rx_availability: u8,
630 }
631
632 struct EncryptionChangeV2(0x59) {
634 status: Status,
635 handle: ConnHandle,
636 encryption_enabled: EncryptionEnabledLevel,
637 encryption_key_size: u8,
638 }
639
640 struct Vendor<'a>(0xff) {
644 params: RemainingBytes<'a>,
645 }
646}
647
648impl<'de> FromHciBytes<'de> for Event<'de> {
649 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
650 let (header, data) = EventPacketHeader::from_hci_bytes(data)?;
651 Self::from_header_hci_bytes(header, data)
652 }
653}
654
655impl<'de> FromHciBytes<'de> for EventPacket<'de> {
656 fn from_hci_bytes(data: &'de [u8]) -> Result<(Self, &'de [u8]), FromHciBytesError> {
657 let (header, data) = EventPacketHeader::from_hci_bytes(data)?;
658 let pkt = Self::from_header_hci_bytes(header, data)?;
659 Ok((pkt, &[]))
660 }
661}
662
663impl<'de> ReadHci<'de> for EventPacket<'de> {
664 const MAX_LEN: usize = 257;
665
666 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
667 let mut header = [0; 2];
668 reader.read_exact(&mut header)?;
669 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
670 let params_len = usize::from(header.params_len);
671 if buf.len() < params_len {
672 Err(ReadHciError::BufferTooSmall)
673 } else {
674 let (buf, _) = buf.split_at_mut(params_len);
675 reader.read_exact(buf)?;
676 let pkt = Self::from_header_hci_bytes(header, buf)?;
677 Ok(pkt)
678 }
679 }
680
681 async fn read_hci_async<R: embedded_io_async::Read>(
682 mut reader: R,
683 buf: &'de mut [u8],
684 ) -> Result<Self, ReadHciError<R::Error>> {
685 let mut header = [0; 2];
686 reader.read_exact(&mut header).await?;
687 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
688 let params_len = usize::from(header.params_len);
689 if buf.len() < params_len {
690 Err(ReadHciError::BufferTooSmall)
691 } else {
692 let (buf, _) = buf.split_at_mut(params_len);
693 reader.read_exact(buf).await?;
694 let pkt = Self::from_header_hci_bytes(header, buf)?;
695 Ok(pkt)
696 }
697 }
698}
699
700impl<'de> ReadHci<'de> for Event<'de> {
701 const MAX_LEN: usize = 257;
702
703 fn read_hci<R: embedded_io::Read>(mut reader: R, buf: &'de mut [u8]) -> Result<Self, ReadHciError<R::Error>> {
704 let mut header = [0; 2];
705 reader.read_exact(&mut header)?;
706 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
707 let params_len = usize::from(header.params_len);
708 if buf.len() < params_len {
709 Err(ReadHciError::BufferTooSmall)
710 } else {
711 let (buf, _) = buf.split_at_mut(params_len);
712 reader.read_exact(buf)?;
713 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
714 Ok(pkt)
715 }
716 }
717
718 async fn read_hci_async<R: embedded_io_async::Read>(
719 mut reader: R,
720 buf: &'de mut [u8],
721 ) -> Result<Self, ReadHciError<R::Error>> {
722 let mut header = [0; 2];
723 reader.read_exact(&mut header).await?;
724 let (header, _) = EventPacketHeader::from_hci_bytes(&header)?;
725 let params_len = usize::from(header.params_len);
726 if buf.len() < params_len {
727 Err(ReadHciError::BufferTooSmall)
728 } else {
729 let (buf, _) = buf.split_at_mut(params_len);
730 reader.read_exact(buf).await?;
731 let (pkt, _) = Self::from_header_hci_bytes(header, buf)?;
732 Ok(pkt)
733 }
734 }
735}
736
737impl CommandComplete<'_> {
738 pub fn has_status(&self) -> bool {
740 self.cmd_opcode != Opcode::UNSOLICITED
741 }
742}
743
744impl<'d> TryFrom<CommandComplete<'d>> for CommandCompleteWithStatus<'d> {
745 type Error = FromHciBytesError;
746 fn try_from(e: CommandComplete<'d>) -> Result<CommandCompleteWithStatus<'d>, Self::Error> {
747 if e.cmd_opcode == Opcode::UNSOLICITED {
748 return Err(FromHciBytesError::InvalidSize);
749 }
750 let bytes = e.bytes.into_inner();
751 let (status, remaining) = Status::from_hci_bytes(bytes)?;
752 let return_param_bytes: RemainingBytes<'d> = RemainingBytes::from_hci_bytes_complete(remaining)?;
753 Ok(Self {
754 num_hci_cmd_pkts: e.num_hci_cmd_pkts,
755 cmd_opcode: e.cmd_opcode,
756 status,
757 return_param_bytes,
758 })
759 }
760}
761
762#[derive(Debug, Clone, PartialEq, Eq)]
764pub struct CommandCompleteWithStatus<'d> {
765 pub num_hci_cmd_pkts: u8,
767 pub cmd_opcode: Opcode,
769 pub status: Status,
771 pub return_param_bytes: RemainingBytes<'d>,
773}
774
775impl CommandCompleteWithStatus<'_> {
776 pub fn handle<C: SyncCmd>(&self) -> Result<C::Handle, FromHciBytesError> {
781 C::return_handle(&self.return_param_bytes)
782 }
783
784 pub fn to_result<C: SyncCmd>(&self) -> Result<C::Return, Error> {
791 self.status
792 .to_result()
793 .and_then(|_| self.return_params::<C>().or(Err(Error::INVALID_HCI_PARAMETERS)))
794 }
795
796 pub fn return_params<C: SyncCmd>(&self) -> Result<C::Return, FromHciBytesError> {
803 assert_eq!(self.cmd_opcode, C::OPCODE);
804 C::Return::from_hci_bytes(&self.return_param_bytes).and_then(|(params, rest)| {
805 if rest.is_empty() {
806 Ok(params)
807 } else {
808 Err(FromHciBytesError::InvalidSize)
809 }
810 })
811 }
812}
813
814#[derive(Debug, Clone, PartialEq, Eq)]
816pub struct InquiryResultItem {
817 pub bd_addr: BdAddr,
819 pub page_scan_repetition_mode: Option<PageScanRepetitionMode>,
821 pub class_of_device: Option<[u8; 3]>,
823 pub clock_offset: Option<ClockOffset>,
825 pub rssi: Option<i8>,
828}
829
830pub struct InquiryResultIter<'a> {
832 bytes: &'a [u8],
833 num_responses: usize,
834 idx: usize,
835 kind: InquiryResultKind,
836}
837
838#[derive(Copy, Clone, Debug, PartialEq, Eq)]
840pub enum InquiryResultKind {
841 Standard,
843 WithRssi,
845}
846
847impl<'a> InquiryResultIter<'a> {
848 pub fn new_standard(bytes: &'a [u8], num_responses: usize) -> Self {
850 InquiryResultIter {
851 bytes,
852 num_responses,
853 idx: 0,
854 kind: InquiryResultKind::Standard,
855 }
856 }
857
858 pub fn new_with_rssi(bytes: &'a [u8], num_responses: usize) -> Self {
860 InquiryResultIter {
861 bytes,
862 num_responses,
863 idx: 0,
864 kind: InquiryResultKind::WithRssi,
865 }
866 }
867}
868
869impl Iterator for InquiryResultIter<'_> {
870 type Item = InquiryResultItem;
871 fn next(&mut self) -> Option<Self::Item> {
872 if self.idx >= self.num_responses {
873 return None;
874 }
875
876 let i = self.idx;
877 let n = self.num_responses;
878
879 let bd_addr_size = n * 6;
880 let page_scan_size = n;
881 let class_size = n * 3;
882 let clock_size = n * 2;
883
884 let reserved_size = match self.kind {
885 InquiryResultKind::Standard => n * 2,
886 InquiryResultKind::WithRssi => n,
887 };
888
889 let bd_addr_off = i * 6;
890 let page_scan_off = bd_addr_size + i;
891 let class_off = bd_addr_size + page_scan_size + reserved_size + i * 3;
892 let clock_off = bd_addr_size + page_scan_size + reserved_size + class_size + i * 2;
893
894 if self.bytes.len() < bd_addr_off + 6 {
895 return None;
896 }
897
898 let bd_addr = BdAddr::new([
899 self.bytes[bd_addr_off],
900 self.bytes[bd_addr_off + 1],
901 self.bytes[bd_addr_off + 2],
902 self.bytes[bd_addr_off + 3],
903 self.bytes[bd_addr_off + 4],
904 self.bytes[bd_addr_off + 5],
905 ]);
906
907 let page_scan_repetition_mode = self
908 .bytes
909 .get(page_scan_off)
910 .and_then(|b| PageScanRepetitionMode::from_hci_bytes(&[*b]).ok().map(|(m, _)| m));
911
912 let class_of_device = self.bytes.get(class_off..class_off + 3).map(|s| [s[0], s[1], s[2]]);
913
914 let clock_offset = self
915 .bytes
916 .get(clock_off..clock_off + 2)
917 .and_then(|s| ClockOffset::from_hci_bytes(s).ok().map(|(c, _)| c));
918
919 let rssi = if self.kind == InquiryResultKind::WithRssi {
920 let rssi_off = bd_addr_size + page_scan_size + reserved_size + class_size + clock_size + i;
921 self.bytes.get(rssi_off).map(|b| *b as i8)
922 } else {
923 None
924 };
925
926 self.idx += 1;
927
928 Some(InquiryResultItem {
929 bd_addr,
930 page_scan_repetition_mode,
931 class_of_device,
932 clock_offset,
933 rssi,
934 })
935 }
936}
937
938impl InquiryResult<'_> {
940 pub fn iter(&self) -> InquiryResultIter<'_> {
942 let bytes = self.bytes.as_hci_bytes();
943 let n = self.num_responses as usize;
944 InquiryResultIter::new_standard(bytes, n)
945 }
946}
947
948impl InquiryResultWithRssi<'_> {
950 pub fn iter(&self) -> InquiryResultIter<'_> {
952 let bytes = self.bytes.as_hci_bytes();
953 let n = self.num_responses as usize;
954 InquiryResultIter::new_with_rssi(bytes, n)
955 }
956}
957
958#[cfg(test)]
959mod tests {
960 use super::*;
961 use crate::cmd::OpcodeGroup;
962 use crate::event::le::LeEventPacket;
963 use crate::param::*;
964
965 #[test]
966 fn test_inquiry_result() {
967 let data = [
968 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, ];
976 let (inquiry_result, _) = InquiryResult::from_hci_bytes(&data).unwrap();
977
978 let mut iter = inquiry_result.iter();
979
980 let item1 = iter.next().unwrap();
981 assert_eq!(item1.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
982 assert_eq!(item1.page_scan_repetition_mode, Some(PageScanRepetitionMode::R1));
983 assert_eq!(item1.class_of_device, Some([0x20, 0x04, 0x00]));
984 assert_eq!(item1.clock_offset.unwrap().as_hci_bytes(), &[0x34, 0x12]);
985 assert_eq!(item1.rssi, None);
986
987 let item2 = iter.next().unwrap();
988 assert_eq!(item2.bd_addr.as_hci_bytes(), &[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
989 assert_eq!(item2.page_scan_repetition_mode, Some(PageScanRepetitionMode::R2));
990 assert_eq!(item2.class_of_device, Some([0x30, 0x05, 0x01]));
991 assert_eq!(item2.clock_offset.unwrap().as_hci_bytes(), &[0x78, 0x56]);
992 assert_eq!(item2.rssi, None);
993 assert!(iter.next().is_none());
994 }
995
996 #[test]
997 fn test_inquiry_result_with_rssi() {
998 let data = [
999 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, ];
1008 let (inquiry_result, _) = InquiryResultWithRssi::from_hci_bytes(&data).unwrap();
1009
1010 let mut iter = inquiry_result.iter();
1011
1012 let item1 = iter.next().unwrap();
1013 assert_eq!(item1.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
1014 assert_eq!(item1.page_scan_repetition_mode, Some(PageScanRepetitionMode::R1));
1015 assert_eq!(item1.class_of_device, Some([0x20, 0x04, 0x00]));
1016 assert_eq!(item1.clock_offset.unwrap().as_hci_bytes(), &[0x34, 0x12]);
1017 assert_eq!(item1.rssi, Some(-16));
1018
1019 let item2 = iter.next().unwrap();
1020 assert_eq!(item2.bd_addr.as_hci_bytes(), &[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
1021 assert_eq!(item2.page_scan_repetition_mode, Some(PageScanRepetitionMode::R2));
1022 assert_eq!(item2.class_of_device, Some([0x30, 0x05, 0x01]));
1023 assert_eq!(item2.clock_offset.unwrap().as_hci_bytes(), &[0x78, 0x56]);
1024 assert_eq!(item2.rssi, Some(-24));
1025 assert!(iter.next().is_none());
1026 }
1027
1028 #[test]
1029 fn test_extended_inquiry_result() {
1030 let data = [
1031 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, ];
1040 let (eir_result, _) = ExtendedInquiryResult::from_hci_bytes(&data).unwrap();
1041
1042 assert_eq!(eir_result.num_responses, 1);
1043 assert_eq!(eir_result.bd_addr.as_hci_bytes(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
1044 assert_eq!(eir_result.page_scan_repetition_mode, PageScanRepetitionMode::R1);
1045 assert_eq!(eir_result.reserved, 0x00);
1046 assert_eq!(eir_result.class_of_device, [0x20, 0x04, 0x00]);
1047 assert_eq!(eir_result.clock_offset.as_hci_bytes(), &[0x34, 0x12]);
1048 assert_eq!(eir_result.rssi, -16);
1049 assert_eq!(
1050 eir_result.eir_data.as_hci_bytes(),
1051 &[0x09, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x76]
1052 );
1053 }
1054
1055 #[test]
1056 fn test_io_capability_request() {
1057 let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
1058 let (evt, rest) = IoCapabilityRequest::from_hci_bytes(&data).unwrap();
1059 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1060 assert!(rest.is_empty());
1061 }
1062
1063 #[test]
1064 fn test_user_confirmation_request() {
1065 let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x78, 0x56, 0x34, 0x12];
1066 let (evt, rest) = UserConfirmationRequest::from_hci_bytes(&data).unwrap();
1067 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1068 assert_eq!(evt.numeric_value, 0x1234_5678);
1069 assert!(rest.is_empty());
1070 }
1071
1072 #[test]
1073 fn test_connection_request() {
1074 let data = [
1075 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x20, 0x04, 0x00, 0x01, ];
1079 let (evt, rest) = ConnectionRequest::from_hci_bytes(&data).unwrap();
1080 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1081 assert_eq!(evt.class_of_device, [0x20, 0x04, 0x00]);
1082 assert_eq!(evt.link_type, ConnectionLinkType::Acl);
1083 assert!(rest.is_empty());
1084 }
1085
1086 #[test]
1087 fn test_role_change() {
1088 let data = [
1089 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, ];
1093 let (evt, rest) = RoleChange::from_hci_bytes(&data).unwrap();
1094 assert_eq!(evt.status, Status::SUCCESS);
1095 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1096 assert_eq!(evt.new_role, Role::Central);
1097 assert!(rest.is_empty());
1098 }
1099
1100 #[test]
1101 fn test_simple_pairing_complete() {
1102 let data = [
1103 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, ];
1106 let (evt, rest) = SimplePairingComplete::from_hci_bytes(&data).unwrap();
1107 assert_eq!(evt.status, Status::SUCCESS);
1108 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1109 assert!(rest.is_empty());
1110 }
1111
1112 #[test]
1113 fn test_io_capability_response() {
1114 let data = [
1115 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x00, 0x03, ];
1120 let (evt, rest) = IoCapabilityResponse::from_hci_bytes(&data).unwrap();
1121 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1122 assert_eq!(evt.io_capability, IoCapability::DisplayYesNo);
1123 assert_eq!(evt.oob_data_present, OobDataPresent::NotPresent);
1124 assert_eq!(
1125 evt.authentication_requirements,
1126 AuthenticationRequirements::MitmRequiredDedicatedBonding
1127 );
1128 assert!(rest.is_empty());
1129 }
1130
1131 #[test]
1132 fn test_number_of_completed_data_blocks() {
1133 let data = [
1134 0x00, 0x10, 0x02, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, ];
1143 let (evt, rest) = NumberOfCompletedDataBlocks::from_hci_bytes(&data).unwrap();
1144 assert_eq!(evt.total_num_data_blocks, 4096);
1145 assert_eq!(evt.num_of_handles, 2);
1146 assert_eq!(evt.bytes.as_hci_bytes().len(), 12); assert!(rest.is_empty());
1148 }
1149
1150 #[test]
1151 fn test_connectionless_peripheral_broadcast_receive() {
1152 let data = [
1153 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x00, 0x01, 0x04, 0xAA, 0xBB, 0xCC, 0xDD, ];
1162 let (evt, rest) = ConnectionlessPeripheralBroadcastReceive::from_hci_bytes(&data).unwrap();
1163 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1164 assert_eq!(evt.lt_addr, 0x07);
1165 assert_eq!(evt.clock, 0x78563412);
1166 assert_eq!(evt.offset, 0xF0DEBC9A);
1167 assert_eq!(evt.rx_status, 0x00);
1168 assert_eq!(evt.fragment, 0x01);
1169 assert_eq!(evt.data_length, 0x04);
1170 assert_eq!(evt.data.as_hci_bytes(), &[0xAA, 0xBB, 0xCC, 0xDD]);
1171 assert!(rest.is_empty());
1172 }
1173
1174 #[test]
1175 fn test_connectionless_peripheral_broadcast_timeout() {
1176 let data = [
1177 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ];
1180 let (evt, rest) = ConnectionlessPeripheralBroadcastTimeout::from_hci_bytes(&data).unwrap();
1181 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1182 assert_eq!(evt.lt_addr, 0x07);
1183 assert!(rest.is_empty());
1184 }
1185
1186 #[test]
1187 fn test_truncated_page_complete() {
1188 let data = [
1189 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, ];
1192 let (evt, rest) = TruncatedPageComplete::from_hci_bytes(&data).unwrap();
1193 assert_eq!(evt.status, Status::SUCCESS);
1194 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1195 assert!(rest.is_empty());
1196 }
1197
1198 #[test]
1199 fn test_peripheral_page_response_timeout() {
1200 let data = [];
1201 let (_evt, rest) = PeripheralPageResponseTimeout::from_hci_bytes(&data).unwrap();
1202 assert!(rest.is_empty());
1203 }
1204
1205 #[test]
1206 fn test_connectionless_peripheral_broadcast_channel_map_change() {
1207 let data = [
1208 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, ];
1210 let (evt, rest) = ConnectionlessPeripheralBroadcastChannelMapChange::from_hci_bytes(&data).unwrap();
1211 assert_eq!(
1212 evt.channel_map,
1213 [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A]
1214 );
1215 assert!(rest.is_empty());
1216 }
1217
1218 #[test]
1219 fn test_sam_status_change() {
1220 let data = [
1221 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ];
1229 let (evt, rest) = SamStatusChange::from_hci_bytes(&data).unwrap();
1230 assert_eq!(evt.handle.raw(), 1);
1231 assert_eq!(evt.local_sam_index, 0x02);
1232 assert_eq!(evt.local_sam_tx_availability, 0x03);
1233 assert_eq!(evt.local_sam_rx_availability, 0x04);
1234 assert_eq!(evt.remote_sam_index, 0x05);
1235 assert_eq!(evt.remote_sam_tx_availability, 0x06);
1236 assert_eq!(evt.remote_sam_rx_availability, 0x07);
1237 assert!(rest.is_empty());
1238 }
1239
1240 #[test]
1241 fn convert_error_packet() {
1242 let data = [
1243 0x04, 10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x20, 0x04, 0x00, 0x01, ];
1247 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1248 assert!(matches!(event.kind, EventKind::ConnectionRequest));
1249
1250 let Event::ConnectionRequest(evt) = Event::try_from(event).unwrap() else {
1251 unreachable!()
1252 };
1253
1254 assert_eq!(evt.bd_addr.raw(), [1, 2, 3, 4, 5, 6]);
1255 assert_eq!(evt.class_of_device, [0x20, 0x04, 0x00]);
1256 assert_eq!(evt.link_type, ConnectionLinkType::Acl);
1257 }
1258
1259 #[test]
1260 fn convert_le_error_packet() {
1261 let data = [
1262 0x3e, 19, 1, 0, 1, 0, 0, 1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 1, ];
1274 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1275 assert!(matches!(event.kind, EventKind::Le));
1276
1277 let Event::Le(LeEvent::LeConnectionComplete(e)) = Event::try_from(event).unwrap() else {
1278 unreachable!()
1279 };
1280
1281 assert_eq!(e.status, Status::SUCCESS);
1282 assert_eq!(e.handle, ConnHandle::new(1));
1283 assert!(matches!(e.central_clock_accuracy, ClockAccuracy::Ppm250));
1284 }
1285
1286 #[test]
1287 fn parse_le_packet() {
1288 let data = [
1289 0x3e, 19, 1, 0, 1, 0, 0, 1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 1, ];
1301 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1302 assert!(matches!(event.kind, EventKind::Le));
1303 let event = LeEventPacket::from_hci_bytes_complete(event.data).unwrap();
1304 assert!(matches!(
1305 event.kind,
1306 crate::event::le::LeEventKind::LeConnectionComplete
1307 ));
1308 let e = crate::event::le::LeConnectionComplete::from_hci_bytes_complete(event.data).unwrap();
1309
1310 assert_eq!(e.status, Status::SUCCESS);
1311 assert_eq!(e.handle, ConnHandle::new(1));
1312 assert!(matches!(e.central_clock_accuracy, ClockAccuracy::Ppm250));
1313 }
1314
1315 #[test]
1316 fn test_special_command_complete() {
1317 let data = [
1318 0x0e, 3, 1, 0, 0, ];
1321
1322 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1323 assert!(matches!(event.kind, EventKind::CommandComplete));
1324 let event = CommandComplete::from_hci_bytes_complete(event.data).unwrap();
1325 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::new(0), 0));
1326 }
1327
1328 #[test]
1329 fn test_normal_command_complete() {
1330 let opcode = Opcode::new(OpcodeGroup::LE, 0x000D).to_raw().to_le_bytes();
1331 let data = [
1332 0x0e, 4, 1, opcode[0], opcode[1], 0, ];
1336
1337 let event = EventPacket::from_hci_bytes_complete(&data).unwrap();
1338 assert!(matches!(event.kind, EventKind::CommandComplete));
1339 let event = CommandComplete::from_hci_bytes_complete(event.data).unwrap();
1340 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::LE, 0x000d));
1341
1342 let event: CommandCompleteWithStatus = event.try_into().unwrap();
1343 assert_eq!(event.cmd_opcode, Opcode::new(OpcodeGroup::LE, 0x000d));
1344 assert_eq!(Status::SUCCESS, event.status);
1345 }
1346}