stm32wb_hci/event/mod.rs
1//! Bluetooth events and event deserialization.
2//!
3//! This module defines all of the HCI events that can be generated by the Bluetooth controller. In
4//! addition to all of the event types, the core functionality of the module is the `Event` enum,
5//! which converts a byte buffer into an HCI event.
6
7#![macro_use]
8
9/// Verifies that the length of the LHS expression is exactly the RHS expression. Fails with a
10/// [`BadLength`](crate::event::Error::BadLength) error if not.
11#[macro_export]
12macro_rules! require_len {
13 ($left:expr, $right:expr) => {
14 if $left.len() != $right {
15 return Err($crate::event::Error::BadLength($left.len(), $right));
16 }
17 };
18}
19
20/// Verifies that the length of the LHS expression is greater than or equal to the RHS expression.
21/// Fails with a [`BadLength`](crate::event::Error::BadLength) error if not.
22#[macro_export]
23macro_rules! require_len_at_least {
24 ($left:expr, $right:expr) => {
25 if $left.len() < $right {
26 return Err($crate::event::Error::BadLength($left.len(), $right));
27 }
28 };
29}
30
31pub mod command;
32
33use crate::types::{ConnectionIntervalError, FixedConnectionInterval};
34use crate::vendor::event::VendorEvent;
35use crate::vendor::VendorError;
36use crate::{BadStatusError, ConnectionHandle, Status};
37use byteorder::{ByteOrder, LittleEndian};
38use core::convert::{TryFrom, TryInto};
39use core::fmt::{Debug, Formatter, Result as FmtResult};
40use core::mem;
41
42/// Potential events that can be generated by the controller.
43///
44/// See the Bluetooth Spec v4.1, Vol 2, Part E, Section 7.7 for a description of each event. The
45/// events are the same for versions 4.1, 4.2, and 5.0 except where noted.
46///
47/// The spec defines an "LE Meta-Event" event. This event is not exposed directly. Instead,
48/// individual LE events are included in this enum.
49#[allow(clippy::large_enum_variant)]
50#[derive(Clone, Debug)]
51#[cfg_attr(feature = "defmt", derive(defmt::Format))]
52pub enum Event {
53 /// Vol 2, Part E, Section 7.7.3
54 ConnectionComplete(ConnectionComplete),
55
56 /// Vol 2, Part E, Section 7.7.5
57 DisconnectionComplete(DisconnectionComplete),
58
59 /// Vol 2, Part E, Section 7.7.8
60 EncryptionChange(EncryptionChange),
61
62 /// Vol 2, Part E, Section 7.7.12
63 ReadRemoteVersionInformationComplete(RemoteVersionInformation),
64
65 /// Vol 2, Part E, Section 7.7.14
66 CommandComplete(command::CommandComplete),
67
68 /// Vol 2, Part E, Section 7.7.15
69 CommandStatus(CommandStatus),
70
71 /// Vol 2, Part E, Section 7.7.16
72 HardwareError(HardwareError),
73
74 /// Vol 2, Part E, Section 7.7.19
75 NumberOfCompletedPackets(NumberOfCompletedPackets),
76
77 /// Vol 2, Part E, Section 7.7.26
78 DataBufferOverflow(DataBufferOverflow),
79
80 /// Vol 2, Part E, Section 7.7.39
81 EncryptionKeyRefreshComplete(EncryptionKeyRefreshComplete),
82
83 /// Vol 2, Part E, Section 7.7.65.1
84 LeConnectionComplete(LeConnectionComplete),
85
86 /// Vol 2, Part E, Section 7.7.65.2
87 LeAdvertisingReport(LeAdvertisingReport),
88
89 /// Vol 2, Part E, Section 7.7.65.3
90 LeConnectionUpdateComplete(LeConnectionUpdateComplete),
91
92 /// Vol 2, Part E, Section 7.7.65.4
93 LeReadRemoteUsedFeaturesComplete(LeReadRemoteUsedFeaturesComplete),
94
95 /// Vol 2, Part E, Section 7.7.65.5
96 LeLongTermKeyRequest(LeLongTermKeyRequest),
97
98 /// Vol 2, Part E, Section 7.7.65.7
99 LeDataLengthChangeEvent(LeDataLengthChangeEvent),
100
101 /// This event is generated when local P-256 key generation is complete.
102 ///
103 /// Vol 4, Part E, 7.7.65.8
104 LeReadLocalP256PublicKeyComplete([u8; 64]),
105
106 /// This event indicates that LE Diffie Hellman key generation has been completed by the Controller.
107 ///
108 /// Vol 4, Part E, Section 7.7.65.9
109 LeGenerateDHKeyComplete([u8; 32]),
110
111 /// Vol 4, Part E, Section 7.7.65.10
112 LeEnhancedConnectionComplete(LeEnhancedConnectionComplete),
113
114 /// Vol 2, Part E, Section 7.7.65.12
115 LePhyUpdateComplete(LePhyUpdateComplete),
116
117 // TODO: le_enhanced_connection_complete
118 // TODO: le_directed_advertising_report
119 // TODO: le_phy_update_complete
120 // TODO: le_extended_advertising_report
121 // TODO: le_scan_timeout
122 // TODO: le_advertising_set_terminated
123 // TODO: le_scan_reauest_received
124 // TODO: le_channel_selection_algorithm
125 /// Vendor-specific events (opcode 0xFF)
126 Vendor(VendorEvent),
127}
128
129/// Errors that may occur when deserializing an event. Must be specialized by the vendor crate to
130/// allow for vendor-specific event errors.
131#[derive(Copy, Clone, Debug, PartialEq)]
132#[cfg_attr(feature = "defmt", derive(defmt::Format))]
133pub enum Error {
134 /// The event type byte was unknown. The byte is provided.
135 UnknownEvent(u8),
136
137 /// The buffer provided that is supposed to contain an event does not have the correct
138 /// length. Field 0 is the provided length, field 1 is the expected length.
139 BadLength(usize, usize),
140
141 /// For all events: The status was not recognized (reserved for future use). Includes the
142 /// unrecognized byte.
143 BadStatus(u8),
144
145 /// For the [Connection Complete](Event::ConnectionComplete) or [Data Buffer Overflow](Event::DataBufferOverflow)
146 /// events: the link type was not recognized (reserved for future use). Includes the unrecognized byte.
147 BadLinkType(u8),
148
149 /// For the [Connection Complete](Event::ConnectionComplete) event: the encryption enabled value
150 /// was not recognized (reserved for future use). Includes the unrecognized byte.
151 BadEncryptionEnabledValue(u8),
152
153 /// For the [Disconnection Complete](Event::DisconnectionComplete) event: the disconnection
154 /// reason was not recognized. Includes the unrecognized byte.
155 BadReason(u8),
156
157 /// For the [Encryption Change](Event::EncryptionChange) event: The encryption type was not
158 /// recognized. Includes the unrecognized byte.
159 BadEncryptionType(u8),
160
161 /// For the [Command Complete](Event::CommandComplete) event: The event indicated a command
162 /// completed whose opcode was not recognized. Includes the unrecognized opcode.
163 UnknownOpcode(crate::opcode::Opcode),
164
165 /// For the [Command Complete](Event::CommandComplete) event, for the Read Local Supported
166 /// Commands command return parameters: The returned command flags are invalid (i.e., they
167 /// include a flag that is reserved for future use).
168 BadCommandFlag,
169
170 /// For the [Command Complete](Event::CommandComplete) event, for the
171 /// [LE Read Channel Map](command::ReturnParameters::LeReadChannelMap) command return parameters:
172 /// The returned channel map includes a reserved bit.
173 InvalidChannelMap([u8; 5]),
174
175 /// For the [Command Complete](Event::CommandComplete) event, for the
176 /// [LE Read Supported States](command::ReturnParameters::LeReadSupportedStates) command return parameters:
177 /// The returned supported states bitfield includes a reserved bit.
178 InvalidLeStates(u64),
179
180 /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The connection role was
181 /// not recognized. Includes the unrecognized byte.
182 BadLeConnectionRole(u8),
183
184 /// For the [LE Connection Complete](Event::LeConnectionComplete) or
185 /// [LE Advertising Report](Event::LeAdvertisingReport) events: The address type was not recognized.
186 /// Includes the unrecognized byte.
187 BadLeAddressType(u8),
188
189 /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The returned connection
190 /// interval was invalid. Includes the error returned when attempting to create the
191 /// [FixedConnectionInterval].
192 BadConnectionInterval(ConnectionIntervalError),
193
194 /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The central clock
195 /// accuracy value was not recognized. Includes the unrecognized byte.
196 BadLeCentralClockAccuracy(u8),
197
198 /// For the [LE Advertising Report](Event::LeAdvertisingReport) event: The packet ended with a
199 /// partial report.
200 LeAdvertisementReportIncomplete,
201
202 /// For the [LE Advertising Report](Event::LeAdvertisingReport) event: The packet includes an
203 /// invalid advertisement type. Includes the unrecognized byte.
204 BadLeAdvertisementType(u8),
205
206 /// For the [LE Read Remote Used Features Complete](Event::LeReadRemoteUsedFeaturesComplete)
207 /// event: The response included an invalid bit set for the remote features. Includes the 8
208 /// bytes of flags.
209 BadRemoteUsedFeatureFlag(u64),
210
211 /// For the [LE PHY Update Complete](Event::LePhyUpdateComplete) event: The PHY type was not
212 /// recognized. Includes the unrecognized byte.
213 BadPhy(u8),
214
215 /// For the [Hardware Error](Event::HardwareError) event: The error code was not recongnized.
216 /// Includes the unrecongnized code.
217 BadHardwareError(u8),
218
219 /// A vendor-specific error was detected when deserializing a vendor-specific event.
220 Vendor(VendorError),
221}
222
223/// Extracts the value from a [`BadStatusError`](BadStatusError) and returns it as a
224/// [`BadStatus`](Error::BadStatus) error.
225pub fn rewrap_bad_status(bad_status: BadStatusError) -> Error {
226 let BadStatusError::BadValue(v) = bad_status;
227 Error::BadStatus(v)
228}
229
230fn rewrap_bad_reason(bad_status: BadStatusError) -> Error {
231 let BadStatusError::BadValue(v) = bad_status;
232 Error::BadReason(v)
233}
234
235fn rewrap_bd_addr_type_err(bad_addr_type: crate::BdAddrTypeError) -> Error {
236 Error::BadLeAddressType(bad_addr_type.0)
237}
238
239/// Defines a newtype to indicate that the buffer is supposed to contain an HCI event.
240pub struct Packet<'a>(pub &'a [u8]);
241
242impl<'a> Packet<'a> {
243 fn full_length(&self) -> usize {
244 PACKET_HEADER_LENGTH + self.0[PARAM_LEN_BYTE] as usize
245 }
246}
247
248const PACKET_HEADER_LENGTH: usize = 2;
249const EVENT_TYPE_BYTE: usize = 0;
250const PARAM_LEN_BYTE: usize = 1;
251
252impl Event {
253 /// Deserializes an event from the given packet. The packet should contain all of the data
254 /// needed to deserialize the event.
255 ///
256 /// # Errors
257 ///
258 /// - [`UnknownEvent`](Error::UnknownEvent) error if the first byte of the header is not a
259 /// recognized event type. This includes events that may be valid BLE events, but are not yet
260 /// be implemented by this crate.
261 /// - [`BadLength`](Error::BadLength) error if the length of the packet is not sufficient to
262 /// either (1) contain a packet header, or (2) contain the packet data as defined by the
263 /// header.
264 /// - Other errors if the particular event cannot be correctly deserialized from the
265 /// packet. This includes vendor-specific errors for vendor events.
266 pub fn new(packet: Packet) -> Result<Event, Error> {
267 require_len_at_least!(packet.0, PACKET_HEADER_LENGTH);
268 require_len!(packet.0, packet.full_length());
269
270 let event_type = packet.0[EVENT_TYPE_BYTE];
271 let payload = &packet.0[PACKET_HEADER_LENGTH..packet.full_length()];
272
273 match event_type {
274 0x03 => Ok(Event::ConnectionComplete(to_connection_complete(payload)?)),
275 0x05 => Ok(Event::DisconnectionComplete(to_disconnection_complete(
276 payload,
277 )?)),
278 0x08 => Ok(Event::EncryptionChange(to_encryption_change(payload)?)),
279 0x0C => Ok(Event::ReadRemoteVersionInformationComplete(
280 to_remote_version_info(payload)?,
281 )),
282 0x0E => Ok(Event::CommandComplete(command::CommandComplete::new(
283 payload,
284 )?)),
285 0x0F => Ok(Event::CommandStatus(to_command_status(payload)?)),
286 0x10 => Ok(Event::HardwareError(to_hardware_error(payload)?)),
287 0x13 => Ok(Event::NumberOfCompletedPackets(
288 to_number_of_completed_packets(payload)?,
289 )),
290 0x1A => Ok(Event::DataBufferOverflow(to_data_buffer_overflow(payload)?)),
291 0x30 => Ok(Event::EncryptionKeyRefreshComplete(
292 to_encryption_key_refresh_complete(payload)?,
293 )),
294 0x3E => to_le_meta_event(payload),
295 0xFF => Ok(Event::Vendor(VendorEvent::new(payload)?)),
296 _ => Err(Error::UnknownEvent(event_type)),
297 }
298 }
299}
300
301fn to_le_meta_event(payload: &[u8]) -> Result<Event, Error> {
302 require_len_at_least!(payload, 1);
303 match payload[0] {
304 0x01 => Ok(Event::LeConnectionComplete(to_le_connection_complete(
305 payload,
306 )?)),
307 0x02 => Ok(Event::LeAdvertisingReport(to_le_advertising_report(
308 payload,
309 )?)),
310 0x03 => Ok(Event::LeConnectionUpdateComplete(
311 to_le_connection_update_complete(payload)?,
312 )),
313 0x04 => Ok(Event::LeReadRemoteUsedFeaturesComplete(
314 to_le_read_remote_used_features_complete(payload)?,
315 )),
316 0x05 => Ok(Event::LeLongTermKeyRequest(to_le_ltk_request(payload)?)),
317 0x07 => Ok(Event::LeDataLengthChangeEvent(
318 to_le_data_length_change_event(payload)?,
319 )),
320 0x08 => Ok(Event::LeReadLocalP256PublicKeyComplete(
321 to_le_read_local_p256_public_key(payload)?,
322 )),
323 0x09 => Ok(Event::LeGenerateDHKeyComplete(
324 to_le_generate_dhkey_complete(payload)?,
325 )),
326 0x0A => Ok(Event::LeEnhancedConnectionComplete(
327 to_le_enhanced_connection_complete(payload)?,
328 )),
329 0x0C => Ok(Event::LePhyUpdateComplete(to_le_phy_update_complete(
330 payload,
331 )?)),
332
333 _ => Err(Error::UnknownEvent(payload[0])),
334 }
335}
336
337/// The [Connection Complete](Event::ConnectionComplete) event indicates to both of the Hosts
338/// forming the connection that a new connection has been established.
339///
340/// This event also indicates to the Host which issued the connection command and then received a
341/// [Command Status](Event::CommandStatus) event, if the issued command failed or was successful.
342#[derive(Copy, Clone, Debug)]
343#[cfg_attr(feature = "defmt", derive(defmt::Format))]
344pub struct ConnectionComplete {
345 /// Did the connection attempt fail, and if so, how?
346 pub status: Status,
347 /// Identifies a connection between two BR/ EDR Controllers. This is used as an identifier for
348 /// transmitting and receiving voice or data.
349 pub conn_handle: ConnectionHandle,
350 /// BD ADDR of the other connected device forming the connection.
351 pub bd_addr: crate::BdAddr,
352 /// Type of connection.
353 pub link_type: LinkType,
354 /// True if the connection is encrypted.
355 pub encryption_enabled: bool,
356}
357
358/// Permissible values for [`ConnectionComplete::link_type`].
359#[derive(Copy, Clone, Debug, PartialEq)]
360#[cfg_attr(feature = "defmt", derive(defmt::Format))]
361pub enum LinkType {
362 /// Synchronous, connection-oriented link
363 Sco,
364 /// Asynchronous, connection-less link
365 Acl,
366}
367
368impl TryFrom<u8> for LinkType {
369 type Error = Error;
370
371 fn try_from(value: u8) -> Result<LinkType, Self::Error> {
372 match value {
373 0 => Ok(LinkType::Sco),
374 1 => Ok(LinkType::Acl),
375 _ => Err(Error::BadLinkType(value)),
376 }
377 }
378}
379
380fn to_connection_complete(payload: &[u8]) -> Result<ConnectionComplete, Error> {
381 require_len!(payload, 11);
382
383 let mut bd_addr = crate::BdAddr([0; 6]);
384 bd_addr.0.copy_from_slice(&payload[3..9]);
385 Ok(ConnectionComplete {
386 status: payload[0].try_into().map_err(rewrap_bad_status)?,
387 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
388 bd_addr,
389 link_type: payload[9].try_into()?,
390 encryption_enabled: try_into_encryption_enabled(payload[10])?,
391 })
392}
393
394fn try_into_encryption_enabled(value: u8) -> Result<bool, Error> {
395 match value {
396 0 => Ok(false),
397 1 => Ok(true),
398 _ => Err(Error::BadEncryptionEnabledValue(value)),
399 }
400}
401
402/// The [Disconnection Complete](Event::DisconnectionComplete) event occurs when a connection is
403/// terminated.
404///
405/// Note: When a physical link fails, one Disconnection Complete event will be returned for each
406/// logical channel on the physical link with the corresponding
407/// [connection handle](DisconnectionComplete::conn_handle) as a parameter.
408///
409/// See the Bluetooth v4.1 spec, Vol 2, Part E, Section 7.7.5.
410#[derive(Copy, Clone, Debug)]
411#[cfg_attr(feature = "defmt", derive(defmt::Format))]
412pub struct DisconnectionComplete {
413 /// Indicates if the disconnection was successful or not.
414 pub status: Status,
415
416 /// Connection handle which was disconnected.
417 pub conn_handle: ConnectionHandle,
418
419 /// Indicates the reason for the disconnection if the disconnection was successful. If the
420 /// disconnection was not successful, the value of the reason parameter can be ignored by the
421 /// Host. For example, this can be the case if the Host has issued the
422 /// [Disconnect](crate::host::HostHci::disconnect) command and there was a parameter error, or the
423 /// command was not presently allowed, or a connection handle that didn't correspond to a
424 /// connection was given.
425 pub reason: Status,
426}
427
428fn to_disconnection_complete(payload: &[u8]) -> Result<DisconnectionComplete, Error> {
429 require_len!(payload, 4);
430
431 Ok(DisconnectionComplete {
432 status: payload[0].try_into().map_err(rewrap_bad_status)?,
433 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
434 reason: payload[3].try_into().map_err(rewrap_bad_reason)?,
435 })
436}
437
438/// The [Encryption Change](Event::EncryptionChange) event is used to indicate that the change of
439/// the encryption mode has been completed.
440///
441/// This event will occur on both devices to notify the Hosts when Encryption has changed for the
442/// specified connection handle between two devices. Note: This event shall not be generated if
443/// encryption is paused or resumed; during a role switch, for example.
444///
445/// See the Bluetooth v4.1 spec, Vol 2, Part E, Section 7.7.8.
446#[derive(Copy, Clone, Debug)]
447#[cfg_attr(feature = "defmt", derive(defmt::Format))]
448pub struct EncryptionChange {
449 /// Indicates if the encryption change was successful or not.
450 pub status: Status,
451
452 /// Connection handle for which the link layer encryption has been enabled/disabled for all
453 /// connection handles with the same BR/EDR Controller endpoint as the specified
454 /// connection handle.
455 ///
456 /// The connection handle will be a connection handle for an ACL connection.
457 pub conn_handle: ConnectionHandle,
458
459 /// Specifies the new encryption type parameter for
460 /// [`conn_handle`](EncryptionChange::conn_handle).
461 pub encryption: Encryption,
462}
463
464/// The type of used encryption for the connection.
465///
466/// The meaning of the encryption type depends on whether the Host has indicated support for Secure
467/// Connections in the secure connections host support parameter. When secure connections host
468/// support is 'disabled' or the connection handle refers to an LE link, the Controller shall only
469/// use values [`Off`](Encryption::Off) and [`On`](Encryption::On). When secure connections host
470/// support is 'enabled' and the connection handle refers to a BR/EDR link, the Controller shall set
471/// the encryption type [`Off`](Encryption::Off) when encryption is off, to [`On`](Encryption::On)
472/// when encryption is on and using E0 and to [`OnAesCcmForBrEdr`](Encryption::OnAesCcmForBrEdr)
473/// when encryption is on and using AES-CCM.
474#[derive(Copy, Clone, Debug, PartialEq)]
475#[cfg_attr(feature = "defmt", derive(defmt::Format))]
476pub enum Encryption {
477 /// Encryption is disabled.
478 Off,
479 /// - On a BR/EDR link, encryption is enabled using E0
480 /// - On an LE link, encryption is enabled using AES-CCM
481 On,
482 /// On a BR/EDR link, encryption is enabled using AES-CCM. Unused for LE links.
483 OnAesCcmForBrEdr,
484}
485
486impl TryFrom<u8> for Encryption {
487 type Error = Error;
488 fn try_from(value: u8) -> Result<Encryption, Self::Error> {
489 match value {
490 0x00 => Ok(Encryption::Off),
491 0x01 => Ok(Encryption::On),
492 0x02 => Ok(Encryption::OnAesCcmForBrEdr),
493 _ => Err(Error::BadEncryptionType(value)),
494 }
495 }
496}
497
498fn to_encryption_change(payload: &[u8]) -> Result<EncryptionChange, Error> {
499 require_len!(payload, 4);
500 Ok(EncryptionChange {
501 status: payload[0].try_into().map_err(rewrap_bad_status)?,
502 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
503 encryption: payload[3].try_into()?,
504 })
505}
506
507/// Indicates the completion of the process obtaining the version information of the remote
508/// Controller specified by [`conn_handle`](RemoteVersionInformation::conn_handle).
509///
510/// See [`RemoteVersionInformationComplete`](Event::ReadRemoteVersionInformationComplete).
511#[derive(Copy, Clone, Debug)]
512#[cfg_attr(feature = "defmt", derive(defmt::Format))]
513pub struct RemoteVersionInformation {
514 /// Status of the read event.
515 pub status: Status,
516
517 /// Connection Handle which was used for the
518 /// [`read_remote_version_information`](crate::host::HostHci::read_remote_version_information)
519 /// command. The connection handle shall be for an ACL connection.
520 pub conn_handle: ConnectionHandle,
521
522 /// Version of the Current LMP in the remote Controller. See [LMP] version and [Link Layer]
523 /// version in the Bluetooth Assigned Numbers.
524 /// - When the connection handle is associated with a BR/EDR ACL-U logical link, the Version
525 /// event parameter shall be LMP version parameter
526 /// - When the connection handle is associated with an LE-U logical link, the Version event
527 /// parameter shall be Link Layer version parameter
528 ///
529 /// [LMP]: https://www.bluetooth.com/specifications/assigned-numbers/link-manager
530 /// [Link Layer]: https://www.bluetooth.com/specifications/assigned-numbers/link-layer
531 pub version: u8,
532
533 /// Manufacturer name of the remote Controller. See [CompId] in the Bluetooth Assigned Numbers.
534 ///
535 /// [CompId]: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
536 pub mfgr_name: u16,
537
538 /// Subversion of the [LMP] in the remote Controller. See the Bluetooth Spec, v4.1, Vol 2, Part
539 /// C, Table 5.2 and Vol 6, Part B, Section 2.4.2.13 (SubVersNr). The sections are the same in
540 /// v4.2 and v5.0 of the spec.
541 ///
542 /// This field shall contain a unique value for each implementation or revision of an
543 /// implementation of the Bluetooth Controller.
544 ///
545 /// The meaning of the subversion is implementation-defined.
546 ///
547 /// [LMP]: https://www.bluetooth.com/specifications/assigned-numbers/link-manager
548 pub subversion: u16,
549}
550
551fn to_remote_version_info(payload: &[u8]) -> Result<RemoteVersionInformation, Error> {
552 require_len!(payload, 8);
553 Ok(RemoteVersionInformation {
554 status: payload[0].try_into().map_err(rewrap_bad_status)?,
555 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
556 version: payload[3],
557 mfgr_name: LittleEndian::read_u16(&payload[4..]),
558 subversion: LittleEndian::read_u16(&payload[6..]),
559 })
560}
561
562/// The [Command Status](Event::CommandStatus) event is used to indicate that the command described
563/// by the [`opcode`](CommandStatus::opcode) parameter has been received, and that the Controller is
564/// currently performing the task for this command.
565///
566/// Defined in Vol 2, Part E, Section 7.7.15 of the spec.
567#[derive(Copy, Clone, Debug)]
568#[cfg_attr(feature = "defmt", derive(defmt::Format))]
569pub struct CommandStatus {
570 /// Status of the command that has started.
571 pub status: Status,
572
573 /// Number of HCI Command packets that can be sent to the controller from the host.
574 pub num_hci_command_packets: u8,
575
576 /// Opcode of the command that generated this event. The controller can generate a spontaneous
577 /// [`Command Status`](Event::CommandStatus) with opcode 0 if the number of allowed HCI commands
578 /// has changed.
579 pub opcode: crate::opcode::Opcode,
580}
581
582fn to_command_status(buffer: &[u8]) -> Result<CommandStatus, Error> {
583 require_len!(buffer, 4);
584
585 Ok(CommandStatus {
586 status: buffer[0].try_into().map_err(rewrap_bad_status)?,
587 num_hci_command_packets: buffer[1],
588 opcode: crate::opcode::Opcode(LittleEndian::read_u16(&buffer[2..])),
589 })
590}
591
592/// The [Hardware Error](Event::HardwareError) event is used to notify the Host that a hardware
593/// failure has occurred in the Controller.
594///
595/// Defined in Vol 2, Part E, Section 7.7.16 of the spec.
596#[derive(Copy, Clone, Debug, PartialEq)]
597#[cfg_attr(feature = "defmt", derive(defmt::Format))]
598pub enum HardwareError {
599 /// Bluecore act2 error detected.
600 Act2 = 0x01,
601 /// Bluecore time overrun error detected.
602 TimeOverrun = 0x02,
603 /// Internal FIFO full.
604 FifoFull = 0x03,
605 /// ISR delay error detected (from cut 2.2).
606 IsrDelay = 0x04,
607}
608
609fn to_hardware_error(payload: &[u8]) -> Result<HardwareError, Error> {
610 require_len!(payload, 1);
611 match payload[0] {
612 0x01 => Ok(HardwareError::Act2),
613 0x02 => Ok(HardwareError::TimeOverrun),
614 0x03 => Ok(HardwareError::FifoFull),
615 0x04 => Ok(HardwareError::IsrDelay),
616 err => Err(Error::BadHardwareError(err)),
617 }
618}
619
620/// The [`Number of Completed Packets`](Event::NumberOfCompletedPackets) event is used by the
621/// Controller to indicate to the Host how many HCI Data Packets have been completed (transmitted or
622/// flushed) for each connection handle since the previous Number Of Completed Packets event was
623/// sent to the Host.
624///
625/// Defined in Vol 2, Part E, Section 7.7.19 of the spec.
626#[derive(Copy, Clone)]
627#[cfg_attr(feature = "defmt", derive(defmt::Format))]
628pub struct NumberOfCompletedPackets {
629 /// Number of connection handles whose data is sent in this event.
630 pub(crate) num_handles: usize,
631
632 /// Data buffer for the event.
633 pub(crate) data_buf: [u8; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN],
634}
635
636// The maximum number of bytes in the buffer is the max HCI packet size (255) less the other data in
637// the packet.
638pub(crate) const NUMBER_OF_COMPLETED_PACKETS_MAX_LEN: usize = 254;
639
640impl Debug for NumberOfCompletedPackets {
641 fn fmt(&self, f: &mut Formatter) -> FmtResult {
642 write!(f, "{{")?;
643 for pair in self.iter() {
644 write!(f, "{:?}", pair)?;
645 }
646 write!(f, "}}")
647 }
648}
649
650impl NumberOfCompletedPackets {
651 pub fn new(items: impl Iterator<Item = NumberOfCompletedPacketsPair>) -> Self {
652 let mut data_buf = [0; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN];
653
654 // let num_handles = &items.count();
655 let mut index = 0;
656 let mut num_handles = 0;
657 for item in items {
658 LittleEndian::write_u16(&mut data_buf[index..], item.conn_handle.0);
659 LittleEndian::write_u16(
660 &mut data_buf[index + 2..],
661 item.num_completed_packets as u16,
662 );
663 index += 4;
664 num_handles += 1;
665 }
666
667 Self {
668 num_handles,
669 data_buf,
670 }
671 }
672
673 /// Returns an iterator over the connection handle-number of completed packet pairs.
674 pub fn iter(&self) -> NumberOfCompletedPacketsIterator {
675 NumberOfCompletedPacketsIterator {
676 event: self,
677 next_index: 0,
678 }
679 }
680}
681
682/// Iterator over the connection handle-number of completed packet pairs from the
683/// [`NumberOfCompletedPackets`] event.
684#[cfg_attr(feature = "defmt", derive(defmt::Format))]
685pub struct NumberOfCompletedPacketsIterator<'a> {
686 event: &'a NumberOfCompletedPackets,
687 next_index: usize,
688}
689
690const NUM_COMPLETED_PACKETS_PAIR_LEN: usize = 4;
691impl<'a> Iterator for NumberOfCompletedPacketsIterator<'a> {
692 type Item = NumberOfCompletedPacketsPair;
693
694 /// Returns the next connection handle-number of completed packets pair from the event.
695 fn next(&mut self) -> Option<Self::Item> {
696 if self.next_index >= self.event.num_handles * NUM_COMPLETED_PACKETS_PAIR_LEN {
697 return None;
698 }
699
700 let index = self.next_index;
701 self.next_index += NUM_COMPLETED_PACKETS_PAIR_LEN;
702 Some(NumberOfCompletedPacketsPair {
703 conn_handle: ConnectionHandle(LittleEndian::read_u16(&self.event.data_buf[index..])),
704 num_completed_packets: LittleEndian::read_u16(&self.event.data_buf[index + 2..])
705 as usize,
706 })
707 }
708}
709
710/// The [`NumberOfCompletedPackets`] event includes a series of connection handle-number of
711/// completed packets pairs.
712#[derive(Copy, Clone, Debug)]
713#[cfg_attr(feature = "defmt", derive(defmt::Format))]
714pub struct NumberOfCompletedPacketsPair {
715 /// Connection handle
716 pub conn_handle: ConnectionHandle,
717 /// The number of HCI Data Packets that have been completed (transmitted or flushed) for
718 /// [`conn_handle`](NumberOfCompletedPacketsPair::conn_handle) since the previous time the event
719 /// was returned.
720 pub num_completed_packets: usize,
721}
722
723fn to_number_of_completed_packets(payload: &[u8]) -> Result<NumberOfCompletedPackets, Error> {
724 require_len_at_least!(payload, 1);
725
726 let num_pairs = payload[0] as usize;
727 require_len!(payload, 1 + num_pairs * NUM_COMPLETED_PACKETS_PAIR_LEN);
728
729 let mut data_buf = [0; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN];
730 data_buf[..num_pairs * NUM_COMPLETED_PACKETS_PAIR_LEN].copy_from_slice(&payload[1..]);
731 Ok(NumberOfCompletedPackets {
732 num_handles: num_pairs,
733 data_buf,
734 })
735}
736
737/// Indicates that the Controller's data buffers have been overflowed. This can occur if the Host
738/// has sent more packets than allowed.
739///
740/// Defined in Vol 2, Part E, Section 7.7.26 of the spec.
741#[derive(Copy, Clone, Debug)]
742#[cfg_attr(feature = "defmt", derive(defmt::Format))]
743pub struct DataBufferOverflow {
744 /// Indicates whether the overflow was caused by ACL or synchronous data.
745 pub link_type: LinkType,
746}
747
748fn to_data_buffer_overflow(payload: &[u8]) -> Result<DataBufferOverflow, Error> {
749 require_len!(payload, 1);
750 Ok(DataBufferOverflow {
751 link_type: payload[0].try_into()?,
752 })
753}
754
755/// Indicates to the Host that the encryption key was refreshed.
756///
757/// The encryption key is refreshed on the given
758/// [`conn_handle`](EncryptionKeyRefreshComplete::conn_handle) any time encryption is paused and
759/// then resumed. The BR/EDR Controller shall send this event when the encryption key has been
760/// refreshed due to encryption being started or resumed.
761///
762/// If the [Encryption Key Refresh Complete](Event::EncryptionKeyRefreshComplete) event was
763/// generated due to an encryption pause and resume operation embedded within a change connection
764/// link key procedure, the Encryption Key Refresh Complete event shall be sent prior to the Change
765/// Connection Link Key Complete event.
766///
767/// If the Encryption Key Refresh Complete event was generated due to an encryption pause and resume
768/// operation embedded within a role switch procedure, the Encryption Key Refresh Complete event
769/// shall be sent prior to the Role Change event.
770///
771/// Defined in Vol 2, Part E, Section 7.7.39 of the spec.
772#[derive(Copy, Clone, Debug)]
773#[cfg_attr(feature = "defmt", derive(defmt::Format))]
774pub struct EncryptionKeyRefreshComplete {
775 /// Did the encryption key refresh fail, and if so, how?
776 pub status: Status,
777 /// Connection Handle for the ACL connection to have the encryption key refreshed on.
778 pub conn_handle: ConnectionHandle,
779}
780
781fn to_encryption_key_refresh_complete(
782 payload: &[u8],
783) -> Result<EncryptionKeyRefreshComplete, Error> {
784 require_len!(payload, 3);
785 Ok(EncryptionKeyRefreshComplete {
786 status: payload[0].try_into().map_err(rewrap_bad_status)?,
787 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
788 })
789}
790
791/// Indicates to both of the Hosts forming the connection that a new connection has been
792/// created. Upon the creation of the connection a connection handle shall be assigned by the
793/// Controller, and passed to the Host in this event. If the connection establishment fails this
794/// event shall be provided to the Host that had issued the [LE Create Connection](crate::host::HostHci::le_create_connection)
795/// command.
796///
797/// This event indicates to the Host which issued a [LE Create Connection](crate::host::Hci::le_create_connection)
798/// command and received a [Command Status](Event::CommandStatus) event if the connection establishment failed or was successful.
799///
800/// Defined in Vol 2, Part E, Section 7.7.65.1 of the spec.
801#[derive(Copy, Clone, Debug)]
802#[cfg_attr(feature = "defmt", derive(defmt::Format))]
803pub struct LeConnectionComplete {
804 /// Did the LE Connection fail, and if so, how?
805 pub status: Status,
806
807 /// Connection handle to be used to identify a connection between two Bluetooth devices. The
808 /// connection handle is used as an identifier for transmitting and receiving data.
809 pub conn_handle: ConnectionHandle,
810
811 /// Role of the device receiving this event in the connection.
812 pub role: ConnectionRole,
813
814 /// Address of the peer device.
815 pub peer_bd_addr: crate::BdAddrType,
816
817 /// Connection interval used on this connection.
818 pub conn_interval: FixedConnectionInterval,
819
820 /// This is only valid for a peripheral. On a central device, this parameter shall be set to
821 /// Ppm500.
822 pub central_clock_accuracy: CentralClockAccuracy,
823}
824
825/// Connection roles as returned by the [LE Connection Complete](Event::LeConnectionComplete) event.
826#[derive(Copy, Clone, Debug, PartialEq)]
827#[cfg_attr(feature = "defmt", derive(defmt::Format))]
828pub enum ConnectionRole {
829 /// The device is the central device for the connection.
830 ///
831 /// The Bluetooth spec refers to these as "master" devices.
832 Central,
833 /// The device is a peripheral device for the connection.
834 ///
835 /// The Bluetooth spec refers to these as "slave" devices.
836 Peripheral,
837}
838
839impl TryFrom<u8> for ConnectionRole {
840 type Error = Error;
841 fn try_from(value: u8) -> Result<ConnectionRole, Self::Error> {
842 match value {
843 0 => Ok(ConnectionRole::Central),
844 1 => Ok(ConnectionRole::Peripheral),
845 _ => Err(Error::BadLeConnectionRole(value)),
846 }
847 }
848}
849
850/// Values for the central (master) clock accuracy as returned by the
851/// [LE Connection Complete](Event::LeConnectionComplete) event.
852#[derive(Copy, Clone, Debug, PartialEq)]
853#[cfg_attr(feature = "defmt", derive(defmt::Format))]
854pub enum CentralClockAccuracy {
855 /// The central clock is accurate to at least 500 parts-per-million. This value is also used
856 /// when the device is a central device.
857 Ppm500,
858 /// The central clock is accurate to at least 250 parts-per-million.
859 Ppm250,
860 /// The central clock is accurate to at least 150 parts-per-million.
861 Ppm150,
862 /// The central clock is accurate to at least 100 parts-per-million.
863 Ppm100,
864 /// The central clock is accurate to at least 75 parts-per-million.
865 Ppm75,
866 /// The central clock is accurate to at least 50 parts-per-million.
867 Ppm50,
868 /// The central clock is accurate to at least 30 parts-per-million.
869 Ppm30,
870 /// The central clock is accurate to at least 20 parts-per-million.
871 Ppm20,
872}
873
874impl TryFrom<u8> for CentralClockAccuracy {
875 type Error = Error;
876 fn try_from(value: u8) -> Result<CentralClockAccuracy, Self::Error> {
877 match value {
878 0 => Ok(CentralClockAccuracy::Ppm500),
879 1 => Ok(CentralClockAccuracy::Ppm250),
880 2 => Ok(CentralClockAccuracy::Ppm150),
881 3 => Ok(CentralClockAccuracy::Ppm100),
882 4 => Ok(CentralClockAccuracy::Ppm75),
883 5 => Ok(CentralClockAccuracy::Ppm50),
884 6 => Ok(CentralClockAccuracy::Ppm30),
885 7 => Ok(CentralClockAccuracy::Ppm20),
886 _ => Err(Error::BadLeCentralClockAccuracy(value)),
887 }
888 }
889}
890
891fn to_le_connection_complete(payload: &[u8]) -> Result<LeConnectionComplete, Error> {
892 require_len!(payload, 19);
893 let mut bd_addr = crate::BdAddr([0; 6]);
894 bd_addr.0.copy_from_slice(&payload[6..12]);
895 Ok(LeConnectionComplete {
896 status: payload[1].try_into().map_err(rewrap_bad_status)?,
897 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
898 role: payload[4].try_into()?,
899 peer_bd_addr: crate::to_bd_addr_type(payload[5], bd_addr)
900 .map_err(rewrap_bd_addr_type_err)?,
901 conn_interval: FixedConnectionInterval::from_bytes(&payload[12..18])
902 .map_err(Error::BadConnectionInterval)?,
903 central_clock_accuracy: payload[18].try_into()?,
904 })
905}
906
907/// The [LE Advertising Report](Event::LeAdvertisingReport) event indicates that a Bluetooth device
908/// or multiple Bluetooth devices have responded to an active scan or received some information
909/// during a passive scan. The Controller may queue these advertising reports and send information
910/// from multiple devices in one event.
911///
912/// For Bluetooth Version 5.0: This event shall only be generated if scanning was enabled using the
913/// [LE Set Scan Enable](crate::host::HostHci::le_set_scan_enable) command. It only reports advertising
914/// events that used legacy advertising PDUs.
915///
916/// Defined in Vol 2, Part E, Section 7.7.65.2 of the spec.
917#[derive(Copy, Clone)]
918#[cfg_attr(feature = "defmt", derive(defmt::Format))]
919pub struct LeAdvertisingReport {
920 data_len: usize,
921 data_buf: [u8; MAX_ADVERTISING_REPORT_LEN],
922}
923
924const MAX_ADVERTISING_REPORT_LEN: usize = 253;
925
926impl LeAdvertisingReport {
927 /// Returns an iterator over the advertisements from the event.
928 pub fn iter(&self) -> LeAdvertisingReportIterator {
929 LeAdvertisingReportIterator {
930 inner_iter: self.inner_iter(),
931 }
932 }
933
934 fn inner_iter(&self) -> LeAdvertisingReportInnerIterator<'_> {
935 LeAdvertisingReportInnerIterator {
936 event_data: &self.data_buf[..self.data_len],
937 next_index: 0,
938 }
939 }
940}
941
942/// Collection of functions to aid in external tests.
943pub mod test_helpers {
944 use super::*;
945
946 /// Create an [`LeAdvertisingReport`] from a slice of [`LeAdvertisement`] structs.
947 ///
948 /// Panics if the resulting report would be too big to fit in a report event.
949 pub fn report_with_advertisements(
950 advertisements: &[LeAdvertisement<'_>],
951 ) -> LeAdvertisingReport {
952 let mut data_len = 0;
953 let mut data_buf = [0; MAX_ADVERTISING_REPORT_LEN];
954
955 for advertisement in advertisements {
956 let event_type_index = data_len;
957 let addr_index = 1 + event_type_index;
958 let data_len_index = 7 + addr_index;
959 let data_start_index = 1 + data_len_index;
960 let rssi_index = data_start_index + advertisement.data.len();
961
962 data_buf[event_type_index] = advertisement.event_type as u8;
963 advertisement
964 .address
965 .copy_into_slice(&mut data_buf[addr_index..data_len_index]);
966 data_buf[data_len_index] = advertisement.data.len() as u8;
967 data_buf[data_start_index..rssi_index].copy_from_slice(advertisement.data);
968 data_buf[rssi_index] =
969 unsafe { mem::transmute::<i8, u8>(advertisement.rssi.unwrap_or(127)) };
970
971 data_len = 1 + rssi_index;
972 }
973
974 LeAdvertisingReport { data_len, data_buf }
975 }
976}
977
978impl Debug for LeAdvertisingReport {
979 fn fmt(&self, f: &mut Formatter) -> FmtResult {
980 write!(f, "{{")?;
981 for report in self.iter() {
982 write!(f, "{:?}", report)?;
983 }
984 write!(f, "}}")
985 }
986}
987
988/// Iterator over the individual LE advertisement responses in the
989/// [LE Advertising Report](Event::LeAdvertisingReport) event.
990#[cfg_attr(feature = "defmt", derive(defmt::Format))]
991pub struct LeAdvertisingReportIterator<'a> {
992 inner_iter: LeAdvertisingReportInnerIterator<'a>,
993}
994
995#[cfg_attr(feature = "defmt", derive(defmt::Format))]
996struct LeAdvertisingReportInnerIterator<'a> {
997 event_data: &'a [u8],
998 next_index: usize,
999}
1000
1001impl<'a> Iterator for LeAdvertisingReportIterator<'a> {
1002 type Item = LeAdvertisement<'a>;
1003
1004 /// Returns the next connection handle-number of completed packets pair from the event.
1005 fn next(&mut self) -> Option<Self::Item> {
1006 self.inner_iter.next().unwrap()
1007 }
1008}
1009
1010impl<'a> LeAdvertisingReportInnerIterator<'a> {
1011 fn next(&mut self) -> Result<Option<LeAdvertisement<'a>>, Error> {
1012 if self.next_index >= self.event_data.len() {
1013 return Ok(None);
1014 }
1015
1016 let event_type_index = self.next_index;
1017 let addr_type_index = event_type_index + 1;
1018 let addr_index = addr_type_index + 1;
1019 let data_len_index = addr_index + 6;
1020 let data_len = self.event_data[data_len_index] as usize;
1021 let data_start_index = data_len_index + 1;
1022 let rssi_index = data_start_index + data_len;
1023 self.next_index = rssi_index + 1;
1024
1025 if self.next_index > self.event_data.len() {
1026 return Err(Error::LeAdvertisementReportIncomplete);
1027 }
1028
1029 let mut bd_addr = crate::BdAddr([0; 6]);
1030 bd_addr
1031 .0
1032 .copy_from_slice(&self.event_data[addr_index..data_len_index]);
1033 Ok(Some(LeAdvertisement {
1034 event_type: self.event_data[event_type_index].try_into()?,
1035 address: crate::to_bd_addr_type(self.event_data[addr_type_index], bd_addr)
1036 .map_err(rewrap_bd_addr_type_err)?,
1037 data: &self.event_data[data_start_index..rssi_index],
1038 rssi: match unsafe { mem::transmute::<u8, i8>(self.event_data[rssi_index]) } {
1039 127 => None,
1040 value => Some(value),
1041 },
1042 }))
1043 }
1044}
1045
1046/// A single advertising report returned by the [LE Advertising Report](Event::LeAdvertisingReport)
1047/// event.
1048#[derive(Copy, Clone, Debug)]
1049#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1050pub struct LeAdvertisement<'a> {
1051 /// Advertising respons type
1052 pub event_type: AdvertisementEvent,
1053 /// Address of the advertising device
1054 pub address: crate::BdAddrType,
1055 /// Advertising or scan response data formatted as defined in Vol 3, Part C, Section 11 of the
1056 /// spec.
1057 pub data: &'a [u8],
1058 /// Received signal strength.
1059 ///
1060 /// - Range is -128 dBm to 20 dBm.
1061 /// - If the controller sends the value 127, `None` is returned here, since that value indicates
1062 /// "RSSI is not available".
1063 pub rssi: Option<i8>,
1064}
1065
1066/// Types of advertisement reports.
1067///
1068/// See [`LeAdvertisement`](crate::event::LeAdvertisement).
1069#[derive(Copy, Clone, Debug, PartialEq)]
1070#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1071pub enum AdvertisementEvent {
1072 /// Connectable undirected advertising
1073 Advertisement,
1074 /// Connectable directed advertising
1075 DirectAdvertisement,
1076 /// Scannable undirected advertising
1077 Scan,
1078 /// Non connectable undirected advertising
1079 NonConnectableAdvertisement,
1080 /// Scan Response
1081 ScanResponse,
1082}
1083
1084impl TryFrom<u8> for AdvertisementEvent {
1085 type Error = Error;
1086
1087 fn try_from(value: u8) -> Result<AdvertisementEvent, Self::Error> {
1088 match value {
1089 0 => Ok(AdvertisementEvent::Advertisement),
1090 1 => Ok(AdvertisementEvent::DirectAdvertisement),
1091 2 => Ok(AdvertisementEvent::Scan),
1092 3 => Ok(AdvertisementEvent::NonConnectableAdvertisement),
1093 4 => Ok(AdvertisementEvent::ScanResponse),
1094 _ => Err(Error::BadLeAdvertisementType(value)),
1095 }
1096 }
1097}
1098
1099fn to_le_advertising_report(payload: &[u8]) -> Result<LeAdvertisingReport, Error> {
1100 let mut check_iter = LeAdvertisingReportInnerIterator {
1101 event_data: &payload[2..],
1102 next_index: 0,
1103 };
1104 while (check_iter.next()?).is_some() {}
1105
1106 let data_len = payload.len() - 2;
1107 let mut data_buf = [0; MAX_ADVERTISING_REPORT_LEN];
1108 data_buf[..data_len].copy_from_slice(&payload[2..]);
1109 Ok(LeAdvertisingReport { data_len, data_buf })
1110}
1111
1112/// Indicates that the Controller process to update the connection has completed.
1113///
1114/// On a peripheral, if no connection parameters are updated, then this event shall not
1115/// be issued.
1116///
1117/// On a central device, this event shall be issued if the
1118/// [`connection_update`](crate::host::HostHci::le_connection_update) command was sent.
1119///
1120/// Note: This event can be issued autonomously by the central device's Controller if it decides to
1121/// change the connection interval based on the range of allowable connection intervals for that
1122/// connection.
1123///
1124/// Note: The parameter values returned in this event may be different from the parameter values
1125/// provided by the Host through the [LE Connection Update](crate::host::HostHci::le_connection_update)
1126/// command or the LE Remote Connection Parameter Request Reply command (Section 7.8.31).
1127///
1128/// Defined in Vol 2, Part E, Section 7.7.65.3 of the spec.
1129#[derive(Copy, Clone, Debug)]
1130#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1131pub struct LeConnectionUpdateComplete {
1132 /// Did the LE Connection Update fail, and if so, how?
1133 pub status: Status,
1134
1135 /// Connection handle to be used to identify a connection between two Bluetooth devices. The
1136 /// connection handle is used as an identifier for transmitting and receiving data.
1137 pub conn_handle: ConnectionHandle,
1138
1139 /// Connection interval used on this connection.
1140 pub conn_interval: FixedConnectionInterval,
1141}
1142
1143fn to_le_connection_update_complete(payload: &[u8]) -> Result<LeConnectionUpdateComplete, Error> {
1144 require_len!(payload, 10);
1145 Ok(LeConnectionUpdateComplete {
1146 status: payload[1].try_into().map_err(rewrap_bad_status)?,
1147 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
1148 conn_interval: FixedConnectionInterval::from_bytes(&payload[4..10])
1149 .map_err(Error::BadConnectionInterval)?,
1150 })
1151}
1152
1153/// Indicates the completion of the process of the Controller obtaining the features used on the
1154/// connection and the features supported by the remote Bluetooth device specified by
1155/// [`conn_handle`](LeReadRemoteUsedFeaturesComplete::conn_handle).
1156///
1157/// Note (v5.0): If the features are requested more than once while a connection exists between the
1158/// two devices, the second and subsequent requests may report a cached copy of the features rather
1159/// than fetching the feature mask again.
1160///
1161/// Defined in Vol 2, Part E, Section 7.7.65.4 of the spec.
1162#[derive(Copy, Clone, Debug)]
1163#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1164pub struct LeReadRemoteUsedFeaturesComplete {
1165 /// Did the read fail, and if so, how?
1166 pub status: Status,
1167 /// Connection handle to be used to identify a connection between two Bluetooth devices.
1168 pub conn_handle: ConnectionHandle,
1169 /// Bit Mask List of used LE features.
1170 pub features: crate::LinkLayerFeature,
1171}
1172
1173fn to_le_read_remote_used_features_complete(
1174 payload: &[u8],
1175) -> Result<LeReadRemoteUsedFeaturesComplete, Error> {
1176 require_len!(payload, 12);
1177
1178 let feature_flags = LittleEndian::read_u64(&payload[4..]);
1179 Ok(LeReadRemoteUsedFeaturesComplete {
1180 status: payload[1].try_into().map_err(rewrap_bad_status)?,
1181 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
1182 features: crate::LinkLayerFeature::from_bits(feature_flags)
1183 .ok_or(Error::BadRemoteUsedFeatureFlag(feature_flags))?,
1184 })
1185}
1186
1187/// The [LE Long Term Key Request](Event::LeLongTermKeyRequest) event indicates that the master
1188/// device is attempting to encrypt or re-encrypt the link and is requesting the Long Term Key from
1189/// the Host. (See Vol 6, Part B, Section 5.1.3).
1190///
1191/// Defined in Vol 2, Part E, Section 7.7.65.5 of the spec.
1192#[derive(Copy, Clone, Debug)]
1193#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1194pub struct LeLongTermKeyRequest {
1195 /// Connection handle to be used to identify a connection between two Bluetooth devices.
1196 pub conn_handle: ConnectionHandle,
1197 /// 64-bit random number.
1198 pub random_value: u64,
1199 /// 16-bit encrypted diversifier
1200 pub encrypted_diversifier: u16,
1201}
1202
1203fn to_le_ltk_request(payload: &[u8]) -> Result<LeLongTermKeyRequest, Error> {
1204 require_len!(payload, 13);
1205
1206 Ok(LeLongTermKeyRequest {
1207 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
1208 random_value: LittleEndian::read_u64(&payload[3..]),
1209 encrypted_diversifier: LittleEndian::read_u16(&payload[11..]),
1210 })
1211}
1212
1213/// Indicates that either the maximum Payload length of a LL DATA PDU
1214/// has changed or the maximum transmission time of packets which contain
1215/// LL Data PDUs.
1216///
1217/// This event is only generated if any of the values have changed.
1218///
1219/// Defined in Vol 2, Part E, Section 7.7.65.7 of the spec.
1220#[derive(Copy, Clone, Debug)]
1221#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1222pub struct LeDataLengthChangeEvent {
1223 /// Connection handle to be used to identify a connection between two Bluetooth devices.
1224 pub conn_handle: ConnectionHandle,
1225 /// Maximum number of octets in a PDU that the lcoal controller
1226 /// will send.
1227 pub max_tx_octets: u16,
1228 /// Maximum time that the local controller will take to send a link
1229 /// layer packet.
1230 pub max_tx_time: u16,
1231 /// Maximum number of octets in a PDU that the local controller
1232 /// expects to receive.
1233 pub max_rx_octets: u16,
1234 /// Maximum time that the local controller expects to take to receive a link
1235 /// layer packet.
1236 pub max_rx_time: u16,
1237}
1238
1239fn to_le_data_length_change_event(payload: &[u8]) -> Result<LeDataLengthChangeEvent, Error> {
1240 require_len!(payload, 11);
1241
1242 Ok(LeDataLengthChangeEvent {
1243 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
1244
1245 max_tx_octets: LittleEndian::read_u16(&payload[3..]),
1246 max_tx_time: LittleEndian::read_u16(&payload[5..]),
1247
1248 max_rx_octets: LittleEndian::read_u16(&payload[7..]),
1249 max_rx_time: LittleEndian::read_u16(&payload[9..]),
1250 })
1251}
1252
1253/// PHY types supported by Bluetooth LE.
1254///
1255/// See Vol 1, Part A, Section 3.2.2 of the spec.
1256#[derive(Copy, Clone, Debug)]
1257#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1258pub enum Phy {
1259 /// The LE 1M PHY supports a datarate of 1 MBit/s.
1260 Le1M,
1261 /// The LE 2M PHY supports a datarate of 2 MBit/s.
1262 Le2M,
1263 /// The LE Coded PHY supports a datarate of either 125 kBit/s or 500 kBit/s.
1264 LeCoded,
1265}
1266
1267impl TryFrom<u8> for Phy {
1268 type Error = Error;
1269
1270 fn try_from(value: u8) -> Result<Self, Self::Error> {
1271 match value {
1272 0 => Ok(Phy::Le1M),
1273 1 => Ok(Phy::Le2M),
1274 2 => Ok(Phy::LeCoded),
1275 other => Err(Error::BadPhy(other)),
1276 }
1277 }
1278}
1279
1280/// Indicates that the controller has changed the transmitter
1281/// or receiver PHY in use.
1282///
1283/// This is either sent in response to a LE Set Phy command,
1284/// or when the controller does an autonomous PHY update.
1285///
1286/// Defined in Vol 4, Part E, Section 7.7.65.12 of the spec.
1287#[derive(Copy, Clone, Debug)]
1288#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1289pub struct LePhyUpdateComplete {
1290 /// Connection handle to be used to identify a connection between two Bluetooth devices.
1291 pub conn_handle: ConnectionHandle,
1292 /// Status of the PHY update.
1293 pub status: Status,
1294 /// PHY used for transmission.
1295 pub tx_phy: Phy,
1296 /// PHY used for reception.
1297 pub rx_phy: Phy,
1298}
1299
1300fn to_le_phy_update_complete(payload: &[u8]) -> Result<LePhyUpdateComplete, Error> {
1301 require_len!(payload, 6);
1302
1303 Ok(LePhyUpdateComplete {
1304 status: payload[1].try_into().map_err(rewrap_bad_status)?,
1305 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
1306 tx_phy: Phy::try_from(payload[4])?,
1307 rx_phy: Phy::try_from(payload[5])?,
1308 })
1309}
1310
1311fn to_le_read_local_p256_public_key(payload: &[u8]) -> Result<[u8; 64], Error> {
1312 require_len!(payload, 65);
1313
1314 let mut key = [0; 64];
1315 key.copy_from_slice(&payload[1..]);
1316 Ok(key)
1317}
1318
1319fn to_le_generate_dhkey_complete(payload: &[u8]) -> Result<[u8; 32], Error> {
1320 require_len!(payload, 33);
1321
1322 let mut key = [0; 32];
1323 key.copy_from_slice(&payload[1..]);
1324 Ok(key)
1325}
1326
1327/// This event indicates to both of the Hosts forming the connection that a new connection has been created.
1328/// Upon the creation of the connection, a [Connection Handle](ConnectionHandle) shall be assigned to the
1329/// Controller, and passed to the Host in this event.
1330///
1331/// If the connection establishment fails, this event shall be provided to the Host that had issued the
1332/// [LE Create Connection](crate::host::HostHci::le_create_connection) command.
1333///
1334/// If this event is unmasked and [LE Connection Complete](Event::LeConnectionComplete) event is unmasked,
1335/// only the [LE Enhanced Connection Complete](Event::LeEnhancedConnectionComplete) event is sent when a
1336/// new connection has been completed.
1337///
1338/// This event indicates to the Host that issued a [LE Create Connection](crate::host::HostHci::le_create_connection)
1339/// command and received a [Command Status](CommandStatus) event if the connection establishment failed or
1340/// was successful.
1341///
1342/// The [Central Clock Accuracy](LeEnhancedConnectionComplete::central_clock_accuracy) parameter is only valid
1343/// for a Peripheral. On a Central, this parameter is set to 0x00
1344///
1345/// Defined in Vol 4, Part E, Section 7.7.65.10
1346#[derive(Copy, Clone, Debug)]
1347#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1348pub struct LeEnhancedConnectionComplete {
1349 /// Did the LE Connection fail, and if so, how?
1350 pub status: Status,
1351
1352 /// Connection Handle for which the event applies
1353 pub conn_handle: ConnectionHandle,
1354
1355 /// Role of the device receiving this event in the connection.
1356 pub role: ConnectionRole,
1357
1358 /// Address of the peer device.
1359 pub peer_bd_addr: crate::BdAddrType,
1360
1361 /// Resolvable Private Address being used by the local device for this connection.
1362 ///
1363 /// This is only valid when the [Own Address Type](crate::host::OwnAddressType) is set to
1364 /// [Private Fallback Public](crate::host::OwnAddressType::PrivateFallbackPublic) or
1365 /// [Private Fallback Random](crate::host::OwnAddressType::PrivateFallbackRandom).
1366 /// For other [Own Address Type](crate::host::OwnAddressType) values, the Controller shall
1367 /// return all zeros
1368 pub local_resolvable_private_address: crate::BdAddr,
1369
1370 /// Resolvable Private Address being used by the peer device for this connection.
1371 ///
1372 /// This is only valid when the [Peer Address Type](crate::host::PeerAddrType) is set to
1373 /// [Public Identity Address](crate::host::PeerAddrType::PublicIdentityAddress) or
1374 /// [Random Identity Address](crate::host::PeerAddrType::RandomIdentityAddress).
1375 /// For other [Peer Address Type](crate::host::PeerAddrType) values, the Controller shall
1376 /// return all zeros
1377 pub peer_resolvable_private_address: crate::BdAddr,
1378
1379 /// Connection interval used on this connection.
1380 pub conn_interval: FixedConnectionInterval,
1381
1382 /// This is only valid for a peripheral. On a central device, this parameter shall be set to
1383 /// Ppm500.
1384 pub central_clock_accuracy: CentralClockAccuracy,
1385}
1386
1387fn to_le_enhanced_connection_complete(
1388 payload: &[u8],
1389) -> Result<LeEnhancedConnectionComplete, Error> {
1390 require_len!(payload, 31);
1391
1392 let mut bd_addr = crate::BdAddr([0; 6]);
1393 bd_addr.0.copy_from_slice(&payload[6..12]);
1394
1395 let mut local_resolvable_private_address = crate::BdAddr([0; 6]);
1396 local_resolvable_private_address
1397 .0
1398 .copy_from_slice(&payload[12..18]);
1399
1400 let mut peer_resolvable_private_address = crate::BdAddr([0; 6]);
1401 peer_resolvable_private_address
1402 .0
1403 .copy_from_slice(&payload[18..24]);
1404
1405 Ok(LeEnhancedConnectionComplete {
1406 status: payload[1].try_into().map_err(rewrap_bad_status)?,
1407 conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
1408 role: payload[4].try_into()?,
1409 peer_bd_addr: crate::to_bd_addr_type(payload[5], bd_addr)
1410 .map_err(rewrap_bd_addr_type_err)?,
1411 local_resolvable_private_address,
1412 peer_resolvable_private_address,
1413 conn_interval: FixedConnectionInterval::from_bytes(&payload[24..30])
1414 .map_err(Error::BadConnectionInterval)?,
1415 central_clock_accuracy: payload[30].try_into()?,
1416 })
1417}